Re: [FFmpeg-devel] [PATCH 0/3] *** VDPAU: HEVC YUV 4:4:4 Support ***
On Fri, 26 Apr 2019 09:43:39 +0530 ManojGuptaBonda wrote: > Latest generation video decoder on Turing Chips supports decoding HEVC > 4:4:4 decoding. These changes adds support for the same for VDPAU > > ManojGuptaBonda (3): > VDPAU: Add support for decoding HEVC 4:4:4 content > Pass sps and pps range extension flags to VDPAU. > Map 444 pix fmts to new VdpYCbCr types defined in VDPAU. > > libavcodec/hevcdec.c| 9 +++- > libavcodec/vdpau_hevc.c | 41 > + libavcodec/vdpau_internal.h | > 3 +++ libavutil/hwcontext_vdpau.c | 8 > 4 files changed, 56 insertions(+), 5 deletions(-) > Hi Manoj, Thanks for putting these patches together. I'll push these this weekend if there aren't any comments from anyone else. If you're feeling generous, you could take a look at the vdpau opengl interop in mpv and add support for 444 to the direct path. (It already works correctly when using the vdpau mixer). --phil ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [DECISION] Project policy on closed source components
On Sun, 28 Apr 2019 22:02:11 +0200 (CEST) Marton Balint wrote: > Hi All, > > There has been discussion on the mailing list several times about the > inclusion of support for closed source components (codecs, formats, > filters, etc) in the main ffmpeg codebase. > > Also the removal of libNDI happened without general consensus, so a > vote is necessary to justify the removal. > > So here is a call to the voting committee [1] to decide on the > following two questions: > > 1) Should libNDI support be removed from the ffmpeg codebase? I'm conflicted. I agree they violated the licence and they have to answer for that, but the decision to remove it has negatively affected end users who didn't do anything wrong, and respected the licence as understood. Additionally, I'm uncomfortable with the idea that it's being removed because we say it should never have been there in the first place, rather than as a direct response to the licence violation. You might consider that simply playing with semantics but I don't like the idea of moving the goal posts. At least if you say support was removed due to licence violations you make it clear why it's happening. So, I guess I'm voting NO in terms of how and why it was done, and I'd want a proper discussion of how to do it that and what the basis was. > 2) Should patches using closed source libraries which are not > considered "System Libraries" according to the GPL be rejected? I know the question was withdrawn, but this speaks to the issue of making sure we understand why we're accepting or rejecting something. We could say "we'll reject any patches that are LGPL incompatible" which would obviously cover rejection on this basis, but it would also lead to rejecting other open-source components which we think we are comfortable with. We're then left trying to define what we will and won't accept on less precise terms, which leads to the difficulty we have today. You could say "any submissions must be covered by one of the following open source licences", but that will actually allow things that we seem not to want - like a BSD licenced dynamic loader for a closed source library - that's clearly a BSD licenced submission that is LGPL incompatible. Seems messy. It would be easier to construct a policy if we didn't have LGPL-incompatible open-source components. > Deadline for voting is 7 days from now. > > Thanks, > Marton > > [1] > http://lists.ffmpeg.org/pipermail/ffmpeg-devel/2019-April/242574.html > ___ ffmpeg-devel mailing > list ffmpeg-devel@ffmpeg.org > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel > > To unsubscribe, visit link above, or email > ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe". --phil ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH 0/3] *** VDPAU: HEVC YUV 4:4:4 Support ***
On Thu, 25 Apr 2019 22:00:16 -0700 Philip Langdale wrote: > On Fri, 26 Apr 2019 09:43:39 +0530 > ManojGuptaBonda wrote: > > > Latest generation video decoder on Turing Chips supports decoding > > HEVC 4:4:4 decoding. These changes adds support for the same for > > VDPAU > > > > ManojGuptaBonda (3): > > VDPAU: Add support for decoding HEVC 4:4:4 content > > Pass sps and pps range extension flags to VDPAU. > > Map 444 pix fmts to new VdpYCbCr types defined in VDPAU. > > > > libavcodec/hevcdec.c| 9 +++- > > libavcodec/vdpau_hevc.c | 41 > > + libavcodec/vdpau_internal.h | > > 3 +++ libavutil/hwcontext_vdpau.c | 8 > > 4 files changed, 56 insertions(+), 5 deletions(-) > > > > Hi Manoj, > > Thanks for putting these patches together. I'll push these this > weekend if there aren't any comments from anyone else. > I've pushed them with version bumps, changelog, and a couple of fixes to #define checks because you can't check for the PROFILE which was added ages ago. Need to check for the new FORMAT instead. Thanks, --phil ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH 0/3] *** VDPAU: HEVC YUV 4:4:4 Support ***
On Mon, 6 May 2019 03:33:58 + Manoj Bonda wrote: > Thanks Philip for pushing the changes, sorry for the churn. > > I am not familiar with the MPV code much, but from a quick check by > enabling the direct mode for 444 surfaces by modifying the condition > > p->direct_mode = mapper->dst_params.hw_subfmt == IMGFMT_NV12 || > mapper->dst_params.hw_subfmt == IMGFMT_420P || > to > p->direct_mode = mapper->dst_params.hw_subfmt == IMGFMT_NV12 || > mapper->dst_params.hw_subfmt == IMGFMT_420P || > mapper->dst_params.hw_subfmt == IMGFMT_444P; > > the playback seems to be fine. But I see this might be since we are > downscaling the chroma texture in function mapper_map ? > > I don’t see semi-planar formats for 444 in MPV code. > VDPAU OpenGL interop supports only semiplanar surfaces as per the > spec > (https://www.khronos.org/registry/OpenGL/extensions/NV/NV_vdpau_interop2.txt) > I see the proper way to enable direct mode in MPV is to add support > for 444 semiplanar format. Please correct me if I am wrong. I'm surprised it doesn't look more mangled than it does, because the code assumes the format is always NV12 right now. That means it'll take the top left quarter of the chroma plane and use that. Maybe my sample hides the effect. Anyway, yes, it means we need to add an NV24 pix fmt to ffmpeg and then use it in mpv. > Sorry, but I won’t have bandwidth to take up this MPV task now. I > will try to get back to it once I find some time. I'll start looking at it. Thanks for investigating. --phil ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH] avutil: Add NV24 and NV42 pixel formats
These are the 4:4:4 variants of the semi-planar NV12/NV21 formats. I'm surprised we've not had a reason to add them until now, but they are the format that VDPAU uses when doing interop for 4:4:4 surfaces. Signed-off-by: Philip Langdale --- libavutil/pixdesc.c | 24 libavutil/pixfmt.h| 3 +++ libavutil/tests/pixfmt_best.c | 1 + libavutil/version.h | 2 +- 4 files changed, 29 insertions(+), 1 deletion(-) diff --git a/libavutil/pixdesc.c b/libavutil/pixdesc.c index fe38344d73..b97b0665b0 100644 --- a/libavutil/pixdesc.c +++ b/libavutil/pixdesc.c @@ -2320,6 +2320,30 @@ 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_NV24] = { +.name = "nv24", +.nb_components = 3, +.log2_chroma_w = 0, +.log2_chroma_h = 0, +.comp = { +{ 0, 1, 0, 0, 8, 0, 7, 1 },/* Y */ +{ 1, 2, 0, 0, 8, 1, 7, 1 },/* U */ +{ 1, 2, 1, 0, 8, 1, 7, 2 },/* V */ +}, +.flags = AV_PIX_FMT_FLAG_PLANAR, +}, +[AV_PIX_FMT_NV42] = { +.name = "nv42", +.nb_components = 3, +.log2_chroma_w = 0, +.log2_chroma_h = 0, +.comp = { +{ 0, 1, 0, 0, 8, 0, 7, 1 },/* Y */ +{ 1, 2, 1, 0, 8, 1, 7, 2 },/* U */ +{ 1, 2, 0, 0, 8, 1, 7, 1 },/* V */ +}, +.flags = AV_PIX_FMT_FLAG_PLANAR, +}, }; #if FF_API_PLUS1_MINUS1 FF_ENABLE_DEPRECATION_WARNINGS diff --git a/libavutil/pixfmt.h b/libavutil/pixfmt.h index 24d1b7e415..8b54c9415b 100644 --- a/libavutil/pixfmt.h +++ b/libavutil/pixfmt.h @@ -345,6 +345,9 @@ enum AVPixelFormat { AV_PIX_FMT_YUVA444P12BE, ///< planar YUV 4:4:4,36bpp, (1 Cr & Cb sample per 1x1 Y samples), 12b alpha, big-endian AV_PIX_FMT_YUVA444P12LE, ///< planar YUV 4:4:4,36bpp, (1 Cr & Cb sample per 1x1 Y samples), 12b alpha, little-endian +AV_PIX_FMT_NV24, ///< planar YUV 4:4:4, 24bpp, 1 plane for Y and 1 plane for the UV components, which are interleaved (first byte U and the following byte V) +AV_PIX_FMT_NV42, ///< as above, but U and V bytes are swapped + 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/tests/pixfmt_best.c b/libavutil/tests/pixfmt_best.c index e98fcc19a5..53f7264207 100644 --- a/libavutil/tests/pixfmt_best.c +++ b/libavutil/tests/pixfmt_best.c @@ -76,6 +76,7 @@ int main(void) TEST(AV_PIX_FMT_P010, AV_PIX_FMT_YUV420P10); TEST(AV_PIX_FMT_P016, AV_PIX_FMT_YUV420P16); TEST(AV_PIX_FMT_NV16, AV_PIX_FMT_YUV422P); +TEST(AV_PIX_FMT_NV24, AV_PIX_FMT_YUV444P); TEST(AV_PIX_FMT_YUYV422, AV_PIX_FMT_YUV422P); TEST(AV_PIX_FMT_UYVY422, AV_PIX_FMT_YUV422P); TEST(AV_PIX_FMT_BGR565,AV_PIX_FMT_RGB565); diff --git a/libavutil/version.h b/libavutil/version.h index c0968de621..4922e267cc 100644 --- a/libavutil/version.h +++ b/libavutil/version.h @@ -80,7 +80,7 @@ #define LIBAVUTIL_VERSION_MAJOR 56 #define LIBAVUTIL_VERSION_MINOR 26 -#define LIBAVUTIL_VERSION_MICRO 101 +#define LIBAVUTIL_VERSION_MICRO 102 #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ LIBAVUTIL_VERSION_MINOR, \ -- 2.20.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH] avutil: Add NV24 and NV42 pixel formats
On 2019-05-07 14:43, Carl Eugen Hoyos wrote: Am Di., 7. Mai 2019 um 06:33 Uhr schrieb Philip Langdale : These are the 4:4:4 variants of the semi-planar NV12/NV21 formats. I'm surprised we've not had a reason to add them until now, but they are the format that VDPAU uses when doing interop for 4:4:4 surfaces. Is there already a (libswscale) patch that actually uses the new formats? No. I haven't written any swscale code for this yet, although I could, but there's no specific requirement for it. ffmpeg doesn't implement any of the (opengl) interop, but I've got an mpv patch that does it and it needs the pixfmt to be able to work. --phil ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH] swscale: Add support for NV24 and NV42
I don't think this is terribly useful, as the only thing out there that can even handle NV24 content is VDPAU and the only time you have to deal with it is when doing VDPAU OpenGL interop where swscale is irrelevant. In the other cases you can use YV24 (YUV444P). But anyway, I was asked to do this for the sake of completeness. The implementation is pretty straight-forward. Most of the existing NV12 codepaths work regardless of subsampling and are re-used as is. Where necessary I wrote the slightly different NV24 versions. Finally, the one thing that confused me for a long time was the asm specific x86 path that did an explicit exclusion check for NV12. I replaced that with a semi-planar check and also updated the equivalent PPC code, but which I cannot test. Signed-off-by: Philip Langdale --- libswscale/input.c | 2 + libswscale/output.c | 6 ++- libswscale/ppc/swscale_altivec.c | 3 +- libswscale/ppc/swscale_vsx.c | 3 +- libswscale/swscale_unscaled.c| 51 libswscale/utils.c | 2 + libswscale/version.h | 2 +- libswscale/x86/swscale_template.c| 4 +- 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| 2 + tests/ref/fate/filter-pixfmts-scale | 2 + tests/ref/fate/filter-pixfmts-transpose | 2 + tests/ref/fate/filter-pixfmts-vflip | 2 + 19 files changed, 86 insertions(+), 9 deletions(-) diff --git a/libswscale/input.c b/libswscale/input.c index c2dc356b5d..064f8da314 100644 --- a/libswscale/input.c +++ b/libswscale/input.c @@ -1020,9 +1020,11 @@ av_cold void ff_sws_init_input_funcs(SwsContext *c) c->chrToYV12 = uyvyToUV_c; break; case AV_PIX_FMT_NV12: +case AV_PIX_FMT_NV24: c->chrToYV12 = nv12ToUV_c; break; case AV_PIX_FMT_NV21: +case AV_PIX_FMT_NV42: c->chrToYV12 = nv21ToUV_c; break; case AV_PIX_FMT_RGB8: diff --git a/libswscale/output.c b/libswscale/output.c index d3401f0cd1..26b0ff3d48 100644 --- a/libswscale/output.c +++ b/libswscale/output.c @@ -410,7 +410,8 @@ static void yuv2nv12cX_c(SwsContext *c, const int16_t *chrFilter, int chrFilterS const uint8_t *chrDither = c->chrDither8; int i; -if (dstFormat == AV_PIX_FMT_NV12) +if (dstFormat == AV_PIX_FMT_NV12 || +dstFormat == AV_PIX_FMT_NV24) for (i=0; isrcBpc == 8 && c->dstBpc <= 14) { c->hyScale = c->hcScale = hScale_real_altivec; } -if (!is16BPS(dstFormat) && !isNBPS(dstFormat) && -dstFormat != AV_PIX_FMT_NV12 && dstFormat != AV_PIX_FMT_NV21 && +if (!is16BPS(dstFormat) && !isNBPS(dstFormat) && !isSemiPlanarYUV(dstFormat) && dstFormat != AV_PIX_FMT_GRAYF32BE && dstFormat != AV_PIX_FMT_GRAYF32LE && !c->needAlpha) { c->yuv2planeX = yuv2planeX_altivec; diff --git a/libswscale/ppc/swscale_vsx.c b/libswscale/ppc/swscale_vsx.c index 2e20ab388a..069b77985c 100644 --- a/libswscale/ppc/swscale_vsx.c +++ b/libswscale/ppc/swscale_vsx.c @@ -1874,8 +1874,7 @@ av_cold void ff_sws_init_swscale_vsx(SwsContext *c) c->hcscale_fast = hcscale_fast_vsx; } } -if (!is16BPS(dstFormat) && !isNBPS(dstFormat) && -dstFormat != AV_PIX_FMT_NV12 && dstFormat != AV_PIX_FMT_NV21 && +if (!is16BPS(dstFormat) && !isNBPS(dstFormat) && !isSemiPlanarYUV(dstFormat) && dstFormat != AV_PIX_FMT_GRAYF32BE && dstFormat != AV_PIX_FMT_GRAYF32LE && !c->needAlpha) { c->yuv2planeX = yuv2planeX_vsx; diff --git a/libswscale/swscale_unscaled.c b/libswscale/swscale_unscaled.c index be04a236d8..d7cc0bd4c5 100644 --- a/libswscale/swscale_unscaled.c +++ b/libswscale/swscale_unscaled.c @@ -180,6 +180,47 @@ static int nv12ToPlanarWrapper(SwsContext *c, const uint8_t *src[], return srcSliceH; } +static int planarToNv24Wrapper(SwsContext *c, const uint8_t *src[], + int srcStride[], int srcSliceY, + int srcSliceH, uint8_t *dstParam[], + int dstStride[]) +{ +uint8_t *dst = dstParam[1] + dstStride[1] * srcSliceY; + +copyPlane(src[0], srcStride[0], srcSliceY, srcSliceH, c->srcW, + dstParam[0], dstStride[0]); + +if (c->dstFormat == AV_PIX_FMT_NV24) +interleaveBytes(src[1], src[2], dst, c->chrSrcW, (srcSliceH + 1), +
Re: [FFmpeg-devel] [PATCH] swscale: Add support for NV24 and NV42
On Fri, 10 May 2019 11:03:46 +0200 Carl Eugen Hoyos wrote: > Am Fr., 10. Mai 2019 um 07:59 Uhr schrieb Philip Langdale > : > > > > I don't think this is terribly useful, as the only thing out there > > that can even handle NV24 content is VDPAU and the only time you > > have to deal with it is when doing VDPAU OpenGL interop where > > swscale is irrelevant. In the other cases you can use YV24 > > (YUV444P). > > I believe this information was missing from the other commit message > (or I missed it which is absolutely possible). > > Could it be worthwhile to test where within the vdpau / opengl > pipeline an issue is making this patch useful? I mentioned this in the thread around the previous patch. There's no issue - the interop extension always returns semi planar formats by design, previously just nv12 for 420 content but now nv24 for 444 content. As I also mentioned, I've got an mpv patch that uses the new pixel format to correctly handle this case in the interop. Thanks, --phil ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH] swscale: Add support for NV24 and NV42
On Fri, 10 May 2019 09:35:40 +0300 Lauri Kasanen wrote: > > I'm having trouble making out what formats exactly isSemiPlanarYUV() > matches. Are you sure it's an equivalent check? > Well, the check's been in there for quite a while; that's not new. (isPlanarYUV(pix_fmt) && desc->comp[1].plane == desc->comp[2].plane); So, any planar yuv format where component 1 and component 2 are on the same plane. Except for semi planar formats, you expect either all components on the same plane (packed, so not planar) or every component on a separate plain (normal planar). --phil ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH] swscale: Add support for NV24 and NV42
On 2019-05-10 08:12, Lauri Kasanen wrote: On Fri, 10 May 2019 08:07:45 -0700 Philip Langdale wrote: On Fri, 10 May 2019 09:35:40 +0300 Lauri Kasanen wrote: > > I'm having trouble making out what formats exactly isSemiPlanarYUV() > matches. Are you sure it's an equivalent check? > Well, the check's been in there for quite a while; that's not new. (isPlanarYUV(pix_fmt) && desc->comp[1].plane == desc->comp[2].plane); So, any planar yuv format where component 1 and component 2 are on the same plane. Except for semi planar formats, you expect either all components on the same plane (packed, so not planar) or every component on a separate plain (normal planar). Yes, I understand that. I mean: can you list all formats that function matches? For formats that swscale understands: NV12, NV21 P010(BE|LE) P016(BE|LE) and now NV24, NV42. There are also NV16 and NV20(BE|LE) formats which are not supported by swscale. --phil ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH] swscale: Add support for NV24 and NV42
-BEGIN PGP SIGNED MESSAGE- Hash: SHA256 On Sat, 11 May 2019 17:40:41 +0200 Michael Niedermayer wrote: > On Thu, May 09, 2019 at 10:59:12PM -0700, Philip Langdale wrote: > > I don't think this is terribly useful, as the only thing out there > > that can even handle NV24 content is VDPAU and the only time you > > have to deal with it is when doing VDPAU OpenGL interop where > > swscale is irrelevant. In the other cases you can use YV24 > > (YUV444P). > > > > But anyway, I was asked to do this for the sake of completeness. > > > > The implementation is pretty straight-forward. Most of the existing > > NV12 codepaths work regardless of subsampling and are re-used as is. > > Where necessary I wrote the slightly different NV24 versions. > > > > Finally, the one thing that confused me for a long time was the > > asm specific x86 path that did an explicit exclusion check for NV12. > > I replaced that with a semi-planar check and also updated the > > equivalent PPC code, but which I cannot test. > > > > Signed-off-by: Philip Langdale > > --- > > libswscale/input.c | 2 + > > libswscale/output.c | 6 ++- > > libswscale/ppc/swscale_altivec.c | 3 +- > > libswscale/ppc/swscale_vsx.c | 3 +- > > libswscale/swscale_unscaled.c| 51 > > libswscale/utils.c > > | 2 + libswscale/version.h | 2 +- > > libswscale/x86/swscale_template.c| 4 +- > > 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| 2 + > > tests/ref/fate/filter-pixfmts-scale | 2 + > > tests/ref/fate/filter-pixfmts-transpose | 2 + > > tests/ref/fate/filter-pixfmts-vflip | 2 + > > 19 files changed, 86 insertions(+), 9 deletions(-) > > was this tested with up/down scaling ? > > thanks > Yes. - --phil -BEGIN PGP SIGNATURE- iHUEARYIAB0WIQRokRbWmcX6x+Nv+3hgE8jODULZ6QUCXNb+yQAKCRBgE8jODULZ 6eHxAP9gGwsOidh6k77QyWcRLMk8zr2Uh6qizKPT21h9PYzQEwD8CvYOiRAem/qS UrTfd6pFClXNO27PQEL8aeioZqOH7g8= =pTPw -END PGP SIGNATURE- ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 0/3] NV24/NV42 support
As I had to post an update, I've collected the changes together for convenience. Philip Langdale (3): avutil: Add NV24 and NV42 pixel formats swscale: Add support for NV24 and NV42 swscale: Add test for isSemiPlanarYUV to pixdesc_query libavutil/pixdesc.c | 24 +++ libavutil/pixfmt.h | 3 ++ libavutil/tests/pixfmt_best.c| 1 + libavutil/version.h | 2 +- libswscale/input.c | 2 + libswscale/output.c | 6 ++- libswscale/ppc/swscale_altivec.c | 3 +- libswscale/ppc/swscale_vsx.c | 3 +- libswscale/swscale_unscaled.c| 51 libswscale/tests/pixdesc_query.c | 1 + libswscale/utils.c | 2 + libswscale/version.h | 2 +- libswscale/x86/swscale_template.c| 4 +- 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| 2 + tests/ref/fate/filter-pixfmts-scale | 2 + tests/ref/fate/filter-pixfmts-transpose | 2 + tests/ref/fate/filter-pixfmts-vflip | 2 + tests/ref/fate/sws-pixdesc-query | 19 + 25 files changed, 135 insertions(+), 10 deletions(-) -- 2.20.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 1/3] avutil: Add NV24 and NV42 pixel formats
These are the 4:4:4 variants of the semi-planar NV12/NV21 formats. These formats are not used much, so we've never had a reason to add them until now. VDPAU recently added support HEVC 4:4:4 content and when you use the OpenGL interop, the returned surfaces are in NV24 format, so we need the pixel format for media players, even if there's no direct use within ffmpeg. Separately, there are apparently webcams that use NV24, but I've never seen one. Signed-off-by: Philip Langdale --- libavutil/pixdesc.c | 24 libavutil/pixfmt.h| 3 +++ libavutil/tests/pixfmt_best.c | 1 + libavutil/version.h | 2 +- 4 files changed, 29 insertions(+), 1 deletion(-) diff --git a/libavutil/pixdesc.c b/libavutil/pixdesc.c index fe38344d73..b97b0665b0 100644 --- a/libavutil/pixdesc.c +++ b/libavutil/pixdesc.c @@ -2320,6 +2320,30 @@ 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_NV24] = { +.name = "nv24", +.nb_components = 3, +.log2_chroma_w = 0, +.log2_chroma_h = 0, +.comp = { +{ 0, 1, 0, 0, 8, 0, 7, 1 },/* Y */ +{ 1, 2, 0, 0, 8, 1, 7, 1 },/* U */ +{ 1, 2, 1, 0, 8, 1, 7, 2 },/* V */ +}, +.flags = AV_PIX_FMT_FLAG_PLANAR, +}, +[AV_PIX_FMT_NV42] = { +.name = "nv42", +.nb_components = 3, +.log2_chroma_w = 0, +.log2_chroma_h = 0, +.comp = { +{ 0, 1, 0, 0, 8, 0, 7, 1 },/* Y */ +{ 1, 2, 1, 0, 8, 1, 7, 2 },/* U */ +{ 1, 2, 0, 0, 8, 1, 7, 1 },/* V */ +}, +.flags = AV_PIX_FMT_FLAG_PLANAR, +}, }; #if FF_API_PLUS1_MINUS1 FF_ENABLE_DEPRECATION_WARNINGS diff --git a/libavutil/pixfmt.h b/libavutil/pixfmt.h index 24d1b7e415..8b54c9415b 100644 --- a/libavutil/pixfmt.h +++ b/libavutil/pixfmt.h @@ -345,6 +345,9 @@ enum AVPixelFormat { AV_PIX_FMT_YUVA444P12BE, ///< planar YUV 4:4:4,36bpp, (1 Cr & Cb sample per 1x1 Y samples), 12b alpha, big-endian AV_PIX_FMT_YUVA444P12LE, ///< planar YUV 4:4:4,36bpp, (1 Cr & Cb sample per 1x1 Y samples), 12b alpha, little-endian +AV_PIX_FMT_NV24, ///< planar YUV 4:4:4, 24bpp, 1 plane for Y and 1 plane for the UV components, which are interleaved (first byte U and the following byte V) +AV_PIX_FMT_NV42, ///< as above, but U and V bytes are swapped + 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/tests/pixfmt_best.c b/libavutil/tests/pixfmt_best.c index e98fcc19a5..53f7264207 100644 --- a/libavutil/tests/pixfmt_best.c +++ b/libavutil/tests/pixfmt_best.c @@ -76,6 +76,7 @@ int main(void) TEST(AV_PIX_FMT_P010, AV_PIX_FMT_YUV420P10); TEST(AV_PIX_FMT_P016, AV_PIX_FMT_YUV420P16); TEST(AV_PIX_FMT_NV16, AV_PIX_FMT_YUV422P); +TEST(AV_PIX_FMT_NV24, AV_PIX_FMT_YUV444P); TEST(AV_PIX_FMT_YUYV422, AV_PIX_FMT_YUV422P); TEST(AV_PIX_FMT_UYVY422, AV_PIX_FMT_YUV422P); TEST(AV_PIX_FMT_BGR565,AV_PIX_FMT_RGB565); diff --git a/libavutil/version.h b/libavutil/version.h index c0968de621..4922e267cc 100644 --- a/libavutil/version.h +++ b/libavutil/version.h @@ -80,7 +80,7 @@ #define LIBAVUTIL_VERSION_MAJOR 56 #define LIBAVUTIL_VERSION_MINOR 26 -#define LIBAVUTIL_VERSION_MICRO 101 +#define LIBAVUTIL_VERSION_MICRO 102 #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ LIBAVUTIL_VERSION_MINOR, \ -- 2.20.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 3/3] swscale: Add test for isSemiPlanarYUV to pixdesc_query
Lauri had asked me what the semi planar formats were and that reminded me that we could add it to pixdesc_query so we know exactly what the list is. Signed-off-by: Philip Langdale --- libswscale/tests/pixdesc_query.c | 1 + tests/ref/fate/sws-pixdesc-query | 13 + 2 files changed, 14 insertions(+) diff --git a/libswscale/tests/pixdesc_query.c b/libswscale/tests/pixdesc_query.c index a5585c4314..f6dd8bae68 100644 --- a/libswscale/tests/pixdesc_query.c +++ b/libswscale/tests/pixdesc_query.c @@ -32,6 +32,7 @@ static const struct { {"isBE",isBE}, {"isYUV", isYUV}, {"isPlanarYUV", isPlanarYUV}, +{"isSemiPlanarYUV", isSemiPlanarYUV}, {"isRGB", isRGB}, {"Gray",isGray}, {"RGBinInt",isRGBinInt}, diff --git a/tests/ref/fate/sws-pixdesc-query b/tests/ref/fate/sws-pixdesc-query index bc8147e3c7..e23492293e 100644 --- a/tests/ref/fate/sws-pixdesc-query +++ b/tests/ref/fate/sws-pixdesc-query @@ -347,6 +347,19 @@ isPlanarYUV: yuvj440p yuvj444p +isSemiPlanarYUV: + nv12 + nv16 + nv20be + nv20le + nv21 + nv24 + nv42 + p010be + p010le + p016be + p016le + isRGB: 0bgr 0rgb -- 2.20.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 2/3] swscale: Add support for NV24 and NV42
For the sake of completeness, I'm added NV24/NV42 support to swscale, but the specific use-case I noted when adding the pixel formats doesn't require swscale support (because it's OpenGL interop). The implementation is pretty straight-forward. Most of the existing NV12 codepaths work regardless of subsampling and are re-used as is. Where necessary I wrote the slightly different NV24 versions. Finally, the one thing that confused me for a long time was the asm specific x86 path that did an explicit exclusion check for NV12. I replaced that with a semi-planar check and also updated the equivalent PPC code, which Lauri kindly checked. Signed-off-by: Philip Langdale --- libswscale/input.c | 2 + libswscale/output.c | 6 ++- libswscale/ppc/swscale_altivec.c | 3 +- libswscale/ppc/swscale_vsx.c | 3 +- libswscale/swscale_unscaled.c| 51 libswscale/utils.c | 2 + libswscale/version.h | 2 +- libswscale/x86/swscale_template.c| 4 +- 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| 2 + tests/ref/fate/filter-pixfmts-scale | 2 + tests/ref/fate/filter-pixfmts-transpose | 2 + tests/ref/fate/filter-pixfmts-vflip | 2 + tests/ref/fate/sws-pixdesc-query | 6 +++ 20 files changed, 92 insertions(+), 9 deletions(-) diff --git a/libswscale/input.c b/libswscale/input.c index c2dc356b5d..064f8da314 100644 --- a/libswscale/input.c +++ b/libswscale/input.c @@ -1020,9 +1020,11 @@ av_cold void ff_sws_init_input_funcs(SwsContext *c) c->chrToYV12 = uyvyToUV_c; break; case AV_PIX_FMT_NV12: +case AV_PIX_FMT_NV24: c->chrToYV12 = nv12ToUV_c; break; case AV_PIX_FMT_NV21: +case AV_PIX_FMT_NV42: c->chrToYV12 = nv21ToUV_c; break; case AV_PIX_FMT_RGB8: diff --git a/libswscale/output.c b/libswscale/output.c index d3401f0cd1..26b0ff3d48 100644 --- a/libswscale/output.c +++ b/libswscale/output.c @@ -410,7 +410,8 @@ static void yuv2nv12cX_c(SwsContext *c, const int16_t *chrFilter, int chrFilterS const uint8_t *chrDither = c->chrDither8; int i; -if (dstFormat == AV_PIX_FMT_NV12) +if (dstFormat == AV_PIX_FMT_NV12 || +dstFormat == AV_PIX_FMT_NV24) for (i=0; isrcBpc == 8 && c->dstBpc <= 14) { c->hyScale = c->hcScale = hScale_real_altivec; } -if (!is16BPS(dstFormat) && !isNBPS(dstFormat) && -dstFormat != AV_PIX_FMT_NV12 && dstFormat != AV_PIX_FMT_NV21 && +if (!is16BPS(dstFormat) && !isNBPS(dstFormat) && !isSemiPlanarYUV(dstFormat) && dstFormat != AV_PIX_FMT_GRAYF32BE && dstFormat != AV_PIX_FMT_GRAYF32LE && !c->needAlpha) { c->yuv2planeX = yuv2planeX_altivec; diff --git a/libswscale/ppc/swscale_vsx.c b/libswscale/ppc/swscale_vsx.c index a617f76741..75dee5ea58 100644 --- a/libswscale/ppc/swscale_vsx.c +++ b/libswscale/ppc/swscale_vsx.c @@ -2096,8 +2096,7 @@ av_cold void ff_sws_init_swscale_vsx(SwsContext *c) : hScale16To15_vsx; } } -if (!is16BPS(dstFormat) && !isNBPS(dstFormat) && -dstFormat != AV_PIX_FMT_NV12 && dstFormat != AV_PIX_FMT_NV21 && +if (!is16BPS(dstFormat) && !isNBPS(dstFormat) && !isSemiPlanarYUV(dstFormat) && dstFormat != AV_PIX_FMT_GRAYF32BE && dstFormat != AV_PIX_FMT_GRAYF32LE && !c->needAlpha) { c->yuv2planeX = yuv2planeX_vsx; diff --git a/libswscale/swscale_unscaled.c b/libswscale/swscale_unscaled.c index be04a236d8..d7cc0bd4c5 100644 --- a/libswscale/swscale_unscaled.c +++ b/libswscale/swscale_unscaled.c @@ -180,6 +180,47 @@ static int nv12ToPlanarWrapper(SwsContext *c, const uint8_t *src[], return srcSliceH; } +static int planarToNv24Wrapper(SwsContext *c, const uint8_t *src[], + int srcStride[], int srcSliceY, + int srcSliceH, uint8_t *dstParam[], + int dstStride[]) +{ +uint8_t *dst = dstParam[1] + dstStride[1] * srcSliceY; + +copyPlane(src[0], srcStride[0], srcSliceY, srcSliceH, c->srcW, + dstParam[0], dstStride[0]); + +if (c->dstFormat == AV_PIX_FMT_NV24) +interleaveBytes(src[1], src[2], dst, c->chrSrcW, (srcSliceH + 1), +srcStride[1], srcStride[2], dstStride[1]); +
Re: [FFmpeg-devel] [PATCH 2/3] swscale: Add support for NV24 and NV42
-BEGIN PGP SIGNED MESSAGE- Hash: SHA256 On Sun, 12 May 2019 12:54:24 +0200 Michael Niedermayer wrote: > > all these + 1 in the code above look a bit suspect. Can you explain > what they do assuming they are intended Good catch. I should have removed them when I removed the divide by 2. > [...] > > diff --git a/libswscale/utils.c b/libswscale/utils.c > > index df68bcc0d9..1b1f779532 100644 > > --- a/libswscale/utils.c > > +++ b/libswscale/utils.c > > @@ -264,6 +264,8 @@ static const FormatEntry > > format_entries[AV_PIX_FMT_NB] = { [AV_PIX_FMT_YUVA422P12LE] = { 1, > > 1 }, [AV_PIX_FMT_YUVA444P12BE] = { 1, 1 }, > > [AV_PIX_FMT_YUVA444P12LE] = { 1, 1 }, > > +[AV_PIX_FMT_NV24]= { 1, 1 }, > > +[AV_PIX_FMT_NV42]= { 1, 1 }, > > nitpick: this can be aligned prettier They are aligned to the primary alignment within the list. The lines above are exceptions to the existing pattern due to their length. Thanks, - --phil -BEGIN PGP SIGNATURE- iHUEARYIAB0WIQRokRbWmcX6x+Nv+3hgE8jODULZ6QUCXNgw0gAKCRBgE8jODULZ 6ZHpAPoDp3JcLdqjlWr/mo0luxS0UNHwonKuFU04Dpz8FYkw9AD8DL1DC4czUMT7 qPodwqeGY6xKpeNwf6f7OL78pHP3FAM= =+hv7 -END PGP SIGNATURE- ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH] libavfilter/vf_scale_cuda: fix src_pitch for 10bit videos
On Mon, 13 May 2019 11:18:09 + Sergey Svechnikov wrote: > When scaling a 10bit video using scale_cuda filter (witch uses pixel > format AV_PIX_FMT_P010LE), the output video gets distorted. I think > it has something to do with the differences in processing between > cuda_sdk and ffnvcodec with cuda_nvcc (the problem appears after this > commit > https://github.com/FFmpeg/FFmpeg/commit/2544c7ea67ca9521c5de36396bc9ac7058223742). > To solve the problem we should not divide the input frame planes' > linesizes by 2 and leave them as they are. More info, samples and > reproduction steps are here > https://github.com/Svechnikov/ffmpeg-scale-cuda-10bit-problem --- > libavfilter/vf_scale_cuda.c | 4 ++-- 1 file changed, 2 insertions(+), > 2 deletions(-) > > diff --git a/libavfilter/vf_scale_cuda.c b/libavfilter/vf_scale_cuda.c > index c97a802..7fc33ee 100644 > --- a/libavfilter/vf_scale_cuda.c > +++ b/libavfilter/vf_scale_cuda.c > @@ -423,11 +423,11 @@ static int scalecuda_resize(AVFilterContext > *ctx, break; > case AV_PIX_FMT_P010LE: > call_resize_kernel(ctx, s->cu_func_ushort, 1, > - in->data[0], in->width, in->height, > in->linesize[0]/2, > + in->data[0], in->width, in->height, > in->linesize[0], out->data[0], out->width, out->height, > out->linesize[0]/2, 2); > call_resize_kernel(ctx, s->cu_func_ushort2, 2, > - in->data[1], in->width / 2, in->height / > 2, in->linesize[1]/2, > + in->data[1], in->width / 2, in->height / > 2, in->linesize[1], out->data[0] + out->linesize[0] * ((out->height + > 31) & ~0x1f), out->width / 2, out->height / 2, out->linesize[1] / 4, > 2); break; Thanks for reporting the problem. I took a look and identified the precise mistake I made. I dropped the `pixel_size` scaling factor when setting `pitchInBytes`. Here is the fix I intend to apply. diff --git a/libavfilter/vf_scale_cuda.c b/libavfilter/vf_scale_cuda.c index c97a802ddc..ecfd6a1c92 100644 --- a/libavfilter/vf_scale_cuda.c +++ b/libavfilter/vf_scale_cuda.c @@ -357,7 +357,7 @@ static int call_resize_kernel(AVFilterContext *ctx, CUfunction func, int channel .res.pitch2D.numChannels = channels, .res.pitch2D.width = src_width, .res.pitch2D.height = src_height, -.res.pitch2D.pitchInBytes = src_pitch, +.res.pitch2D.pitchInBytes = src_pitch * pixel_size, .res.pitch2D.devPtr = (CUdeviceptr)src_dptr, }; --phil ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 0/3] avfilter/vf_scale_cuda: Various improvements
After Sergey's bug report, I went and fixed a couple of other things I noticed while I was looking at the filter. Philip Langdale (3): avfilter/vf_scale_cuda: Fix incorrect scaling of > 8bit content avfilter/vf_scale_cuda: Add support for YUV444P16 avfilter/vf_scale_cuda: Simplify output plane addressing libavfilter/vf_scale_cuda.c | 41 + 1 file changed, 28 insertions(+), 13 deletions(-) -- 2.20.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 2/3] avfilter/vf_scale_cuda: Add support for YUV444P16
This format is interesting because it's what you get for decoded 10/12bit HEVC 4:4:4. --- libavfilter/vf_scale_cuda.c | 17 - 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/libavfilter/vf_scale_cuda.c b/libavfilter/vf_scale_cuda.c index ecfd6a1c92..a833dcd1a4 100644 --- a/libavfilter/vf_scale_cuda.c +++ b/libavfilter/vf_scale_cuda.c @@ -43,7 +43,8 @@ static const enum AVPixelFormat supported_formats[] = { AV_PIX_FMT_NV12, AV_PIX_FMT_YUV444P, AV_PIX_FMT_P010, -AV_PIX_FMT_P016 +AV_PIX_FMT_P016, +AV_PIX_FMT_YUV444P16, }; #define DIV_UP(a, b) ( ((a) + (b) - 1) / (b) ) @@ -411,6 +412,20 @@ static int scalecuda_resize(AVFilterContext *ctx, out->data[0]+out->linesize[0]*out->height*2, out->width, out->height, out->linesize[0], 1); break; +case AV_PIX_FMT_YUV444P16: +call_resize_kernel(ctx, s->cu_func_ushort, 1, + in->data[0], in->width, in->height, in->linesize[0] / 2, + out->data[0], out->width, out->height, out->linesize[0] / 2, + 2); +call_resize_kernel(ctx, s->cu_func_ushort, 1, + in->data[1], in->width, in->height, in->linesize[1] / 2, + out->data[1], out->width, out->height, out->linesize[1] / 2, + 2); +call_resize_kernel(ctx, s->cu_func_ushort, 1, + in->data[2], in->width, in->height, in->linesize[2] / 2, + out->data[2], out->width, out->height, out->linesize[2] / 2, + 2); +break; case AV_PIX_FMT_NV12: call_resize_kernel(ctx, s->cu_func_uchar, 1, in->data[0], in->width, in->height, in->linesize[0], -- 2.20.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 3/3] avfilter/vf_scale_cuda: Simplify output plane addressing
I'm not sure why this was written the way it was originally. We initialise the plane addresses correctly in hwcontext_cuda so why try and play games to calculate the plane offsets directly in this code? --- libavfilter/vf_scale_cuda.c | 22 +++--- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/libavfilter/vf_scale_cuda.c b/libavfilter/vf_scale_cuda.c index a833dcd1a4..b7cdb81081 100644 --- a/libavfilter/vf_scale_cuda.c +++ b/libavfilter/vf_scale_cuda.c @@ -390,12 +390,12 @@ static int scalecuda_resize(AVFilterContext *ctx, out->data[0], out->width, out->height, out->linesize[0], 1); call_resize_kernel(ctx, s->cu_func_uchar, 1, - in->data[0]+in->linesize[0]*in->height, in->width/2, in->height/2, in->linesize[0]/2, - out->data[0]+out->linesize[0]*out->height, out->width/2, out->height/2, out->linesize[0]/2, + in->data[1], in->width/2, in->height/2, in->linesize[0]/2, + out->data[1], out->width/2, out->height/2, out->linesize[0]/2, 1); call_resize_kernel(ctx, s->cu_func_uchar, 1, - in->data[0]+ ALIGN_UP((in->linesize[0]*in->height*5)/4, s->tex_alignment), in->width/2, in->height/2, in->linesize[0]/2, - out->data[0]+(out->linesize[0]*out->height*5)/4, out->width/2, out->height/2, out->linesize[0]/2, + in->data[2], in->width/2, in->height/2, in->linesize[0]/2, + out->data[2], out->width/2, out->height/2, out->linesize[0]/2, 1); break; case AV_PIX_FMT_YUV444P: @@ -404,12 +404,12 @@ static int scalecuda_resize(AVFilterContext *ctx, out->data[0], out->width, out->height, out->linesize[0], 1); call_resize_kernel(ctx, s->cu_func_uchar, 1, - in->data[0]+in->linesize[0]*in->height, in->width, in->height, in->linesize[0], - out->data[0]+out->linesize[0]*out->height, out->width, out->height, out->linesize[0], + in->data[1], in->width, in->height, in->linesize[0], + out->data[1], out->width, out->height, out->linesize[0], 1); call_resize_kernel(ctx, s->cu_func_uchar, 1, - in->data[0]+in->linesize[0]*in->height*2, in->width, in->height, in->linesize[0], - out->data[0]+out->linesize[0]*out->height*2, out->width, out->height, out->linesize[0], + in->data[2], in->width, in->height, in->linesize[0], + out->data[2], out->width, out->height, out->linesize[0], 1); break; case AV_PIX_FMT_YUV444P16: @@ -433,7 +433,7 @@ static int scalecuda_resize(AVFilterContext *ctx, 1); call_resize_kernel(ctx, s->cu_func_uchar2, 2, in->data[1], in->width/2, in->height/2, in->linesize[1], - out->data[0] + out->linesize[0] * ((out->height + 31) & ~0x1f), out->width/2, out->height/2, out->linesize[1]/2, + out->data[1], out->width/2, out->height/2, out->linesize[1]/2, 1); break; case AV_PIX_FMT_P010LE: @@ -443,7 +443,7 @@ static int scalecuda_resize(AVFilterContext *ctx, 2); call_resize_kernel(ctx, s->cu_func_ushort2, 2, in->data[1], in->width / 2, in->height / 2, in->linesize[1]/2, - out->data[0] + out->linesize[0] * ((out->height + 31) & ~0x1f), out->width / 2, out->height / 2, out->linesize[1] / 4, + out->data[1], out->width / 2, out->height / 2, out->linesize[1] / 4, 2); break; case AV_PIX_FMT_P016LE: @@ -453,7 +453,7 @@ static int scalecuda_resize(AVFilterContext *ctx, 2); call_resize_kernel(ctx, s->cu_func_ushort2, 2, in->data[1], in->width / 2, in->height / 2, in->linesize[1] / 2, - out->data[0] + out->linesize[0] * ((out->height + 31) & ~0x1f), out->width / 2, out->height / 2, out->linesize[1] / 4, + out->data[1], out->width / 2, out->height / 2, out->linesize[1] / 4, 2); break; default: -- 2.20.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 1/3] avfilter/vf_scale_cuda: Fix incorrect scaling of > 8bit content
When i converted the filter to use texture objects instead of texture references, I incorrect dropped the `pixel_size` scaling factor when setting `pitchInBytes`. `src_pitch` is in pixels and so must be scaled up. --- libavfilter/vf_scale_cuda.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavfilter/vf_scale_cuda.c b/libavfilter/vf_scale_cuda.c index c97a802ddc..ecfd6a1c92 100644 --- a/libavfilter/vf_scale_cuda.c +++ b/libavfilter/vf_scale_cuda.c @@ -357,7 +357,7 @@ static int call_resize_kernel(AVFilterContext *ctx, CUfunction func, int channel .res.pitch2D.numChannels = channels, .res.pitch2D.width = src_width, .res.pitch2D.height = src_height, -.res.pitch2D.pitchInBytes = src_pitch, +.res.pitch2D.pitchInBytes = src_pitch * pixel_size, .res.pitch2D.devPtr = (CUdeviceptr)src_dptr, }; -- 2.20.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH] movsub_bsf: Fix mov2textsub regression
On Sun, 23 Jun 2019 06:46:12 +0200 Andreas Rheinhardt wrote: > The mov flavour of timed text uses the first two bytes of the packet > as a length field. And up until 11bef2fe said length field has been > read correctly in the mov2textsub bsf. But since then the next two > bytes are read as if they were the length field. This is fixed in > this commit. > > Signed-off-by: Andreas Rheinhardt > --- > libavcodec/movsub_bsf.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/libavcodec/movsub_bsf.c b/libavcodec/movsub_bsf.c > index 5878607061..cd48aa7bb8 100644 > --- a/libavcodec/movsub_bsf.c > +++ b/libavcodec/movsub_bsf.c > @@ -75,8 +75,8 @@ static int mov2textsub(AVBSFContext *ctx, AVPacket > *pkt) return AVERROR_INVALIDDATA; > } > > -pkt->data += 2; > pkt->size = FFMIN(pkt->size - 2, AV_RB16(pkt->data)); > +pkt->data += 2; > > return 0; > } LGTM --phil ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH] MAINTAINERS: add myself to the AMF section
On Tue, 02 Jul 2019 17:19:02 +0300 Alexander Kravchenko wrote: > LGTM, but please try and get git send-email working. Your client is still doing binary attachments. --phil ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH 1/2] build: add support for building CUDA files with clang
On 2019-07-30 15:51, Rodger Combs wrote: This avoids using the CUDA SDK at all; instead, we provide a minimal reimplementation of the basic functionality that lavfi actually uses. It generates very similar code to what NVCC produces. The header contains no implementation code derived from the SDK. The function and type declarations are derived from the SDK only to the extent required to build a compatible implementation. This is generally accepted to qualify as fair use. Because this option does not require the proprietary SDK, it does not require the "--enable-nonfree" flag in configure. --- This is awesome. Thanks so much for doing it. I'm not in a position to test, and won't be for a couple of weeks, but I'm happy with you just pushing it - it's strictly no worse than what we have today. --phil ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH 2/2] lavfi/vf_thumbnail_cuda: fix operator precedence bug
On 2019-07-30 15:51, Rodger Combs wrote: Discovered via a warning when building with clang --- libavfilter/vf_thumbnail_cuda.cu | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavfilter/vf_thumbnail_cuda.cu b/libavfilter/vf_thumbnail_cuda.cu index c73e49fbc6..d4d4d791f6 100644 --- a/libavfilter/vf_thumbnail_cuda.cu +++ b/libavfilter/vf_thumbnail_cuda.cu @@ -71,7 +71,7 @@ __global__ void Thumbnail_ushort2(cudaTextureObject_t ushort2_tex, { ushort2 pixel = tex2D(ushort2_tex, x, y); atomicAdd(&histogram[(pixel.x + 128) >> 8], 1); -atomicAdd(&histogram[256 + (pixel.y + 128) >> 8], 1); +atomicAdd(&histogram[256 + ((pixel.y + 128) >> 8)], 1); } } LGTM --phil ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH] Fixing HW accelerated decoders hanging or throwing error in h263dec
On 2019-08-03 00:09, Timo Rothenpieler wrote: On 02.08.2019 11:18, Stefan Schoenefeld wrote: Hi all, Recently we encountered an issue when decoding a h.263 file: FFmpeg will freeze when decoding h.263 video with NVDEC. Turns out this is not directly related to NVDEC but is a problem that shows with several other HW decoders like VDPAU, though the exact kind of error is different (either error messages or freezing[1]). The root cause is that ff_thread_finish_setup() is called twice per frame from ff_h263_decode_frame(). This is not supported by ff_thread_finish_setup() and specifically checked for and warned against in the functions code. The issue is also specific to hw accelerated decoding only as the second call to ff_thread_finish_setup() is only issued when hw acceleration is on. The fix is simple: add a check that the first call is only send when hw acceleration is off, and the second call only when hw acceleration is on (see attached patch). This works fine as far as I was able to test with vdpau and nvdec/nvcuvid hw decoding. The patch also adds NVDEC to the hw config list if available. I also noticed a secondary issue when browsing through the code which is that, according to documentation, ff_thread_finish_setup() should only be called if the codec implements update_thread_context(), which h263dec does not. The patch does not address this and I'm not sure any action needs to be taken here at all. Thanks, Stefan [1] This is depending on whether or not the hw decoder sets the HWACCEL_CAPS_ASYNC_SAFE flag From 0620ee777a8ba98145bb4781e30a77687c97dbf8 Mon Sep 17 00:00:00 2001 From: Stefan Schoenefeld Date: Fri, 2 Aug 2019 10:52:22 +0200 Subject: [PATCH] Fixing HW accelerated decoders hanging or throwing error messages in h263dec --- libavcodec/h263dec.c | 5 - 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libavcodec/h263dec.c b/libavcodec/h263dec.c index 6f001f6..8ee844e 100644 --- a/libavcodec/h263dec.c +++ b/libavcodec/h263dec.c @@ -614,7 +614,7 @@ retry: if ((ret = ff_mpv_frame_start(s, avctx)) < 0) return ret; -if (!s->divx_packed) +if (!s->divx_packed && !avctx->hwaccel) ff_thread_finish_setup(avctx); This seems correct to me, but I'd like another pair of eyes to look over it. Seems fine to me as well. if (avctx->hwaccel) { @@ -747,6 +747,9 @@ const AVCodecHWConfigInternal *ff_h263_hw_config_list[] = { #if CONFIG_H263_VAAPI_HWACCEL HWACCEL_VAAPI(h263), #endif +#if CONFIG_MPEG4_NVDEC_HWACCEL +HWACCEL_NVDEC(mpeg4), +#endif Probably cleaner to split this into its own patch, but otherwise OK. #if CONFIG_MPEG4_VDPAU_HWACCEL HWACCEL_VDPAU(mpeg4), #endif Thanks for fixing this. I was always confused about whether h.263 was really supported by the hardware or not. Can you provide a link to a reference sample that fails without this change and succeeds with it? --phil ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH v2] libavcodec/amfenc: Vulkan initialization support for encoder.
On 2019-08-08 11:33, OvchinnikovDmitrii wrote: diff --git a/libavcodec/amfenc.c b/libavcodec/amfenc.c index 384d8efc92..f66b95645e 100644 --- a/libavcodec/amfenc.c +++ b/libavcodec/amfenc.c @@ -213,6 +213,7 @@ static int amf_init_from_dxva2_device(AVCodecContext *avctx, AVDXVA2DeviceContex static int amf_init_context(AVCodecContext *avctx) { AmfContext *ctx = avctx->priv_data; +AMFContext1 *context1 = NULL; AMF_RESULT res; av_unused int ret; @@ -311,8 +312,20 @@ static int amf_init_context(AVCodecContext *avctx) if (res == AMF_OK) { av_log(avctx, AV_LOG_VERBOSE, "AMF initialisation succeeded via D3D9.\n"); } else { -av_log(avctx, AV_LOG_ERROR, "AMF initialisation failed via D3D9: error %d.\n", res); -return AVERROR(ENOSYS); +AMFGuid guid = IID_AMFContext1(); +res = ctx->context->pVtbl->QueryInterface(ctx->context, &guid, (void**)&context1); +AMF_RETURN_IF_FALSE(ctx, res == AMF_OK, AVERROR_UNKNOWN, "CreateContext1() failed with error %d\n", res); + +res = context1->pVtbl->InitVulkan(context1, NULL); +context1->pVtbl->Release(context1); +if (res != AMF_OK) { +if (res == AMF_NOT_SUPPORTED) +av_log(avctx, AV_LOG_ERROR, "AMF via Vulkan is not supported on the given device.\n"); +else +av_log(avctx, AV_LOG_ERROR, "AMF failed to initialise on the given Vulkan device: %d.\n", res); +return AVERROR(ENOSYS); +} +av_log(avctx, AV_LOG_VERBOSE, "AMF initialisation succeeded via Vulkan.\n"); } } } It's fully contained in the decoder, so it's fine, and strictly better than before. However, keep in mind that if we ever follow through on adding a Vulkan hwcontext, this would need to be handled in a different way - but we'll deal with that when we get there. I'll push it when I get a chance later today. --phil ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH v2] libavcodec/amfenc: Vulkan initialization support for encoder.
On Tue, 27 Aug 2019 10:08:43 -0700 Philip Langdale wrote: > On 2019-08-08 11:33, OvchinnikovDmitrii wrote: > > > > diff --git a/libavcodec/amfenc.c b/libavcodec/amfenc.c > > index 384d8efc92..f66b95645e 100644 > > --- a/libavcodec/amfenc.c > > +++ b/libavcodec/amfenc.c > > @@ -213,6 +213,7 @@ static int > > amf_init_from_dxva2_device(AVCodecContext *avctx, > > AVDXVA2DeviceContex static int amf_init_context(AVCodecContext > > *avctx) { > > AmfContext *ctx = avctx->priv_data; > > +AMFContext1 *context1 = NULL; > > AMF_RESULT res; > > av_unused int ret; > > > > @@ -311,8 +312,20 @@ static int amf_init_context(AVCodecContext > > *avctx) if (res == AMF_OK) { > > av_log(avctx, AV_LOG_VERBOSE, "AMF initialisation > > succeeded via D3D9.\n"); > > } else { > > -av_log(avctx, AV_LOG_ERROR, "AMF initialisation > > failed via D3D9: error %d.\n", res); > > -return AVERROR(ENOSYS); > > +AMFGuid guid = IID_AMFContext1(); > > +res = > > ctx->context->pVtbl->QueryInterface(ctx->context, &guid, > > (void**)&context1); > > +AMF_RETURN_IF_FALSE(ctx, res == AMF_OK, > > AVERROR_UNKNOWN, "CreateContext1() failed with error %d\n", res); > > + > > +res = context1->pVtbl->InitVulkan(context1, NULL); > > +context1->pVtbl->Release(context1); > > +if (res != AMF_OK) { > > +if (res == AMF_NOT_SUPPORTED) > > +av_log(avctx, AV_LOG_ERROR, "AMF via Vulkan > > is not supported on the given device.\n"); > > +else > > +av_log(avctx, AV_LOG_ERROR, "AMF failed to > > initialise on the given Vulkan device: %d.\n", res); > > +return AVERROR(ENOSYS); > > +} > > +av_log(avctx, AV_LOG_VERBOSE, "AMF initialisation > > succeeded via Vulkan.\n"); > > } > > } > > } > > It's fully contained in the decoder, so it's fine, and strictly better > than before. However, keep in mind that if we ever follow through on > adding a Vulkan hwcontext, this would need to be handled in a > different way - but we'll deal with that when we get there. > > I'll push it when I get a chance later today. Pushed with changelog and micro bump. --phil ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH] avcodec/nvdec: Add support for decoding HEVC 4:4:4 content
The latest generation video decoder on the Turing chips supports decoding HEVC 4:4:4. Supporting this is relatively straight-forward; we need to account for the different chroma format and pick the right output and sw formats at the right times. There was one bug which was the hard-coded assumption that the first chroma plane would be half-height; I fixed this to use the actual shift value on the plane. The output formats ('2', and '3') are currently undocumented but appear to be YUV444P and YUV444P16 based on how they behave. --- libavcodec/hevcdec.c | 2 ++ libavcodec/nvdec.c | 43 +++ 2 files changed, 37 insertions(+), 8 deletions(-) diff --git a/libavcodec/hevcdec.c b/libavcodec/hevcdec.c index a3b5c8cb71..508e093ea3 100644 --- a/libavcodec/hevcdec.c +++ b/libavcodec/hevcdec.c @@ -409,6 +409,8 @@ static enum AVPixelFormat get_format(HEVCContext *s, const HEVCSPS *sps) #endif break; case AV_PIX_FMT_YUV420P12: +case AV_PIX_FMT_YUV444P10: +case AV_PIX_FMT_YUV444P12: #if CONFIG_HEVC_NVDEC_HWACCEL *fmt++ = AV_PIX_FMT_CUDA; #endif diff --git a/libavcodec/nvdec.c b/libavcodec/nvdec.c index e779be3a45..7e5c1791ea 100644 --- a/libavcodec/nvdec.c +++ b/libavcodec/nvdec.c @@ -34,6 +34,9 @@ #include "nvdec.h" #include "internal.h" +#define cudaVideoSurfaceFormat_YUV444P 2 +#define cudaVideoSurfaceFormat_YUV444P16 3 + typedef struct NVDECDecoder { CUvideodecoder decoder; @@ -273,7 +276,8 @@ int ff_nvdec_decode_init(AVCodecContext *avctx) CUVIDDECODECREATEINFO params = { 0 }; -int cuvid_codec_type, cuvid_chroma_format; +cudaVideoSurfaceFormat output_format; +int cuvid_codec_type, cuvid_chroma_format, chroma_444; int ret = 0; sw_desc = av_pix_fmt_desc_get(avctx->sw_pix_fmt); @@ -291,6 +295,7 @@ int ff_nvdec_decode_init(AVCodecContext *avctx) av_log(avctx, AV_LOG_ERROR, "Unsupported chroma format\n"); return AVERROR(ENOSYS); } +chroma_444 = cuvid_chroma_format == cudaVideoChromaFormat_444; if (!avctx->hw_frames_ctx) { ret = ff_decode_get_hw_frames_ctx(avctx, AV_HWDEVICE_TYPE_CUDA); @@ -298,6 +303,21 @@ int ff_nvdec_decode_init(AVCodecContext *avctx) return ret; } +switch (sw_desc->comp[0].depth) { +case 8: +output_format = chroma_444 ? cudaVideoSurfaceFormat_YUV444P : + cudaVideoSurfaceFormat_NV12; +break; +case 10: +case 12: +output_format = chroma_444 ? cudaVideoSurfaceFormat_YUV444P16 : + cudaVideoSurfaceFormat_P016; +break; +default: +av_log(avctx, AV_LOG_ERROR, "Unsupported bit depth\n"); +return AVERROR(ENOSYS); +} + frames_ctx = (AVHWFramesContext*)avctx->hw_frames_ctx->data; params.ulWidth = avctx->coded_width; @@ -305,8 +325,7 @@ int ff_nvdec_decode_init(AVCodecContext *avctx) params.ulTargetWidth = avctx->coded_width; params.ulTargetHeight = avctx->coded_height; params.bitDepthMinus8 = sw_desc->comp[0].depth - 8; -params.OutputFormat= params.bitDepthMinus8 ? - cudaVideoSurfaceFormat_P016 : cudaVideoSurfaceFormat_NV12; +params.OutputFormat= output_format; params.CodecType = cuvid_codec_type; params.ChromaFormat= cuvid_chroma_format; params.ulNumDecodeSurfaces = frames_ctx->initial_pool_size; @@ -388,6 +407,8 @@ static int nvdec_retrieve_data(void *logctx, AVFrame *frame) NVDECFrame*cf = (NVDECFrame*)fdd->hwaccel_priv; NVDECDecoder *decoder = (NVDECDecoder*)cf->decoder_ref->data; +AVHWFramesContext *hwctx = (AVHWFramesContext *)frame->hw_frames_ctx->data; + CUVIDPROCPARAMS vpp = { 0 }; NVDECFrame *unmap_data = NULL; @@ -397,6 +418,7 @@ static int nvdec_retrieve_data(void *logctx, AVFrame *frame) unsigned int pitch, i; unsigned int offset = 0; +int shift_h = 0, shift_v = 0; int ret = 0; vpp.progressive_frame = 1; @@ -433,10 +455,11 @@ static int nvdec_retrieve_data(void *logctx, AVFrame *frame) unmap_data->idx_ref = av_buffer_ref(cf->idx_ref); unmap_data->decoder_ref = av_buffer_ref(cf->decoder_ref); +av_pix_fmt_get_chroma_sub_sample(hwctx->sw_format, &shift_h, &shift_v); for (i = 0; frame->linesize[i]; i++) { frame->data[i] = (uint8_t*)(devptr + offset); frame->linesize[i] = pitch; -offset += pitch * (frame->height >> (i ? 1 : 0)); +offset += pitch * (frame->height >> (i ? shift_v : 0)); } goto finish; @@ -576,7 +599,7 @@ int ff_nvdec_frame_params(AVCodecContext *avctx, { AVHWFramesContext *frames_ctx = (AVHWFramesContext*)hw_frames_ctx->data; const AVPixFmtDescriptor *sw_desc; -int cuvid_codec_type, cuvid_chroma_format; +int cuvid_codec_type, cuvid_chroma_format, chroma_444; sw_desc =
[FFmpeg-devel] [PATCH 0/5] Add nvidia hw decode support for HEVC 4:4:4 content
The new video decoder hardware on Turing GPUs supports HEVC 4:4:4 content. This patch series adds the necessary new pixel formats and implements support in nvdec/nvenc/cuviddec. Philip Langdale (5): avutil: Add YUV444P10_LSB and YUV444P12_LSB pixel formats avcodec/nvdec: Add support for decoding HEVC 4:4:4 content avcodec/nvdec: Explicitly mark codecs that support 444 output formats avcodec/cuviddec: Add support for decoding HEVC 4:4:4 content avcodec/nvenc: Accept YUV444P10_LSB and YUV444P12_LSB content Changelog | 1 + libavcodec/cuviddec.c | 59 ++ libavcodec/hevcdec.c | 3 ++ libavcodec/nvdec.c | 46 +++-- libavcodec/nvdec.h | 5 +++- libavcodec/nvdec_h264.c| 2 +- libavcodec/nvdec_hevc.c| 10 +-- libavcodec/nvdec_mjpeg.c | 2 +- libavcodec/nvdec_mpeg12.c | 2 +- libavcodec/nvdec_mpeg4.c | 2 +- libavcodec/nvdec_vc1.c | 2 +- libavcodec/nvdec_vp8.c | 2 +- libavcodec/nvdec_vp9.c | 2 +- libavcodec/nvenc.c | 18 libavcodec/version.h | 2 +- libavutil/hwcontext_cuda.c | 2 ++ libavutil/pixdesc.c| 48 +++ libavutil/pixfmt.h | 8 ++ libavutil/version.h| 4 +-- 19 files changed, 174 insertions(+), 46 deletions(-) -- 2.17.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 1/5] avutil: Add YUV444P10_LSB and YUV444P12_LSB pixel formats
Currently, ffmpeg defines a set of YUV444P formats for use where the bits-per-pixel are between 8 and 16 bits. In these formats, the bits are packed in the MSBs of the 16 bits of available storage. On the other hand, all the hardware vendors have defined their equivalent formats with the bits packed in the LSBs, which has the virtue of making the memory layouts compatible with being treated as full 16 bit values (which is also why P010 is defined this way). So, to be able to use these hardware compatible formats, we need definitions for them in ffmpeg. Right now, I need this for nvdec, but Vulkan also uses the same format definitions. Signed-off-by: Philip Langdale --- libavutil/pixdesc.c | 48 + libavutil/pixfmt.h | 8 libavutil/version.h | 4 ++-- 3 files changed, 58 insertions(+), 2 deletions(-) diff --git a/libavutil/pixdesc.c b/libavutil/pixdesc.c index 970a83214c..c48a100907 100644 --- a/libavutil/pixdesc.c +++ b/libavutil/pixdesc.c @@ -1629,6 +1629,54 @@ 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_YUV444P10LE_LSB] = { +.name = "yuv444p10lelsb", +.nb_components = 3, +.log2_chroma_w = 0, +.log2_chroma_h = 0, +.comp = { +{ 0, 2, 0, 6, 10, 1, 9, 1 },/* Y */ +{ 1, 2, 0, 6, 10, 1, 9, 1 },/* U */ +{ 2, 2, 0, 6, 10, 1, 9, 1 },/* V */ +}, +.flags = AV_PIX_FMT_FLAG_PLANAR, +}, +[AV_PIX_FMT_YUV444P10BE_LSB] = { +.name = "yuv444p10belsb", +.nb_components = 3, +.log2_chroma_w = 0, +.log2_chroma_h = 0, +.comp = { +{ 0, 2, 0, 6, 10, 1, 9, 1 },/* Y */ +{ 1, 2, 0, 6, 10, 1, 9, 1 },/* U */ +{ 2, 2, 0, 6, 10, 1, 9, 1 },/* V */ +}, +.flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR, +}, +[AV_PIX_FMT_YUV444P12LE_LSB] = { +.name = "yuv444p12lelsb", +.nb_components = 3, +.log2_chroma_w = 0, +.log2_chroma_h = 0, +.comp = { +{ 0, 2, 0, 4, 12, 1, 11, 1 },/* Y */ +{ 1, 2, 0, 4, 12, 1, 11, 1 },/* U */ +{ 2, 2, 0, 4, 12, 1, 11, 1 },/* V */ +}, +.flags = AV_PIX_FMT_FLAG_PLANAR, +}, +[AV_PIX_FMT_YUV444P12BE_LSB] = { +.name = "yuv444p12belsb", +.nb_components = 3, +.log2_chroma_w = 0, +.log2_chroma_h = 0, +.comp = { +{ 0, 2, 0, 4, 12, 1, 11, 1 },/* Y */ +{ 1, 2, 0, 4, 12, 1, 11, 1 },/* U */ +{ 2, 2, 0, 4, 12, 1, 11, 1 },/* V */ +}, +.flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR, +}, [AV_PIX_FMT_D3D11VA_VLD] = { .name = "d3d11va_vld", .log2_chroma_w = 1, diff --git a/libavutil/pixfmt.h b/libavutil/pixfmt.h index 6815f8dc7b..910cb0a995 100644 --- a/libavutil/pixfmt.h +++ b/libavutil/pixfmt.h @@ -340,6 +340,11 @@ enum AVPixelFormat { AV_PIX_FMT_GRAYF32BE, ///< IEEE-754 single precision Y, 32bpp, big-endian AV_PIX_FMT_GRAYF32LE, ///< IEEE-754 single precision Y, 32bpp, little-endian +AV_PIX_FMT_YUV444P10LE_LSB, ///< planar YUV 4:4:4, 30bpp, (1 Cr & Cb sample per 1x1 Y samples), LSB packed, little-endian +AV_PIX_FMT_YUV444P10BE_LSB, ///< planar YUV 4:4:4, 30bpp, (1 Cr & Cb sample per 1x1 Y samples), LSB packed, big-endian +AV_PIX_FMT_YUV444P12LE_LSB, ///< planar YUV 4:4:4, 36bpp, (1 Cr & Cb sample per 1x1 Y samples), LSB packed, little-endian +AV_PIX_FMT_YUV444P12BE_LSB, ///< planar YUV 4:4:4, 36bpp, (1 Cr & Cb sample per 1x1 Y samples), LSB packed, big-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 }; @@ -391,6 +396,9 @@ enum AVPixelFormat { #define AV_PIX_FMT_YUV422P16 AV_PIX_FMT_NE(YUV422P16BE, YUV422P16LE) #define AV_PIX_FMT_YUV444P16 AV_PIX_FMT_NE(YUV444P16BE, YUV444P16LE) +#define AV_PIX_FMT_YUV444P10_LSB AV_PIX_FMT_NE(YUV444P10BE_LSB, YUV444P10LE_LSB) +#define AV_PIX_FMT_YUV444P12_LSB AV_PIX_FMT_NE(YUV444P12BE_LSB, YUV444P12LE_LSB) + #define AV_PIX_FMT_GBRP9 AV_PIX_FMT_NE(GBRP9BE ,GBRP9LE) #define AV_PIX_FMT_GBRP10AV_PIX_FMT_NE(GBRP10BE,GBRP10LE) #define AV_PIX_FMT_GBRP12AV_PIX_FMT_NE(GBRP12BE,GBRP12LE) diff --git a/libavutil/version.h b/libavutil/version.h index f84ec89154..377714a91e 100644 --- a/libavutil/version.h +++ b/libavutil/version.h @@ -79,8 +79,8 @@ */ #define LIBAVUTIL_VERSION_MAJOR 56 -#define LIBAVUTIL_VERSION_MINOR 19 -#define LIBAVUTIL_VERSION_MICRO 101 +#define LIBAVUTIL_VERSION_MINOR 20
[FFmpeg-devel] [PATCH 4/5] avcodec/cuviddec: Add support for decoding HEVC 4:4:4 content
This is the equivalent change for cuviddec after the previous change for nvdec. I made similar changes to the copying routines to handle pixel formats in a more generic way. Note that unlike with nvdec, there is no confusion about the ability of a codec to output 444 formats. This is because the cuvid parser is used, meaning that 444 JPEG content is still indicated as using a 420 output format. Signed-off-by: Philip Langdale --- libavcodec/cuviddec.c | 59 +-- 1 file changed, 40 insertions(+), 19 deletions(-) diff --git a/libavcodec/cuviddec.c b/libavcodec/cuviddec.c index 4d3caf924e..595249475d 100644 --- a/libavcodec/cuviddec.c +++ b/libavcodec/cuviddec.c @@ -35,6 +35,9 @@ #include "hwaccel.h" #include "internal.h" +#define CUVID_FORMAT_YUV444P 2 +#define CUVID_FORMAT_YUV444P16 3 + typedef struct CuvidContext { AVClass *avclass; @@ -127,6 +130,7 @@ static int CUDAAPI cuvid_handle_video_sequence(void *opaque, CUVIDEOFORMAT* form CUVIDDECODECAPS *caps = NULL; CUVIDDECODECREATEINFO cuinfo; int surface_fmt; +int chroma_444; int old_width = avctx->width; int old_height = avctx->height; @@ -169,17 +173,19 @@ static int CUDAAPI cuvid_handle_video_sequence(void *opaque, CUVIDEOFORMAT* form cuinfo.target_rect.right = cuinfo.ulTargetWidth; cuinfo.target_rect.bottom = cuinfo.ulTargetHeight; +chroma_444 = format->chroma_format == cudaVideoChromaFormat_444; + switch (format->bit_depth_luma_minus8) { case 0: // 8-bit -pix_fmts[1] = AV_PIX_FMT_NV12; +pix_fmts[1] = chroma_444 ? AV_PIX_FMT_YUV444P : AV_PIX_FMT_NV12; caps = &ctx->caps8; break; case 2: // 10-bit -pix_fmts[1] = AV_PIX_FMT_P010; +pix_fmts[1] = chroma_444 ? AV_PIX_FMT_YUV444P10_LSB : AV_PIX_FMT_P010; caps = &ctx->caps10; break; case 4: // 12-bit -pix_fmts[1] = AV_PIX_FMT_P016; +pix_fmts[1] = chroma_444 ? AV_PIX_FMT_YUV444P12_LSB : AV_PIX_FMT_P016; caps = &ctx->caps12; break; default: @@ -282,12 +288,6 @@ static int CUDAAPI cuvid_handle_video_sequence(void *opaque, CUVIDEOFORMAT* form return 0; } -if (format->chroma_format != cudaVideoChromaFormat_420) { -av_log(avctx, AV_LOG_ERROR, "Chroma formats other than 420 are not supported\n"); -ctx->internal_error = AVERROR(EINVAL); -return 0; -} - ctx->chroma_format = format->chroma_format; cuinfo.CodecType = ctx->codec_type = format->codec; @@ -301,6 +301,14 @@ static int CUDAAPI cuvid_handle_video_sequence(void *opaque, CUVIDEOFORMAT* form case AV_PIX_FMT_P016: cuinfo.OutputFormat = cudaVideoSurfaceFormat_P016; break; +case AV_PIX_FMT_YUV444P: +cuinfo.OutputFormat = CUVID_FORMAT_YUV444P; +break; +case AV_PIX_FMT_YUV444P10_LSB: +case AV_PIX_FMT_YUV444P12_LSB: +case AV_PIX_FMT_YUV444P16: +cuinfo.OutputFormat = CUVID_FORMAT_YUV444P16; +break; default: av_log(avctx, AV_LOG_ERROR, "Output formats other than NV12, P010 or P016 are not supported\n"); ctx->internal_error = AVERROR(EINVAL); @@ -507,6 +515,7 @@ static int cuvid_output_frame(AVCodecContext *avctx, AVFrame *frame) return ret; if (av_fifo_size(ctx->frame_queue)) { +const AVPixFmtDescriptor *pixdesc; CuvidParsedFrame parsed_frame; CUVIDPROCPARAMS params; unsigned int pitch = 0; @@ -537,7 +546,10 @@ static int cuvid_output_frame(AVCodecContext *avctx, AVFrame *frame) goto error; } -for (i = 0; i < 2; i++) { +pixdesc = av_pix_fmt_desc_get(avctx->sw_pix_fmt); + +for (i = 0; i < pixdesc->nb_components; i++) { +size_t height = avctx->height >> (i ? pixdesc->log2_chroma_h : 0); CUDA_MEMCPY2D cpy = { .srcMemoryType = CU_MEMORYTYPE_DEVICE, .dstMemoryType = CU_MEMORYTYPE_DEVICE, @@ -547,22 +559,27 @@ static int cuvid_output_frame(AVCodecContext *avctx, AVFrame *frame) .dstPitch = frame->linesize[i], .srcY = offset, .WidthInBytes = FFMIN(pitch, frame->linesize[i]), -.Height= avctx->height >> (i ? 1 : 0), +.Height= height, }; ret = CHECK_CU(ctx->cudl->cuMemcpy2DAsync(&cpy, device_hwctx->stream)); if (ret < 0) goto error; -offset += avctx->height; +offset += height; } ret = CHECK_CU(ctx->cudl->cuStreamSynchronize(device_hwctx->stream)); if (ret < 0)
[FFmpeg-devel] [PATCH 3/5] avcodec/nvdec: Explicitly mark codecs that support 444 output formats
With the introduction of HEVC 444 support, we technically have two codecs that can handle 444 - HEVC and MJPEG. In the case of MJPEG, it can decode, but can only output one of the semi-planar formats. That means we need additional logic to decide whether to use a 444 output format or not. Signed-off-by: Philip Langdale --- libavcodec/nvdec.c| 7 --- libavcodec/nvdec.h| 5 - libavcodec/nvdec_h264.c | 2 +- libavcodec/nvdec_hevc.c | 10 -- libavcodec/nvdec_mjpeg.c | 2 +- libavcodec/nvdec_mpeg12.c | 2 +- libavcodec/nvdec_mpeg4.c | 2 +- libavcodec/nvdec_vc1.c| 2 +- libavcodec/nvdec_vp8.c| 2 +- libavcodec/nvdec_vp9.c| 2 +- 10 files changed, 23 insertions(+), 13 deletions(-) diff --git a/libavcodec/nvdec.c b/libavcodec/nvdec.c index e1ac06f852..4d1f55b49a 100644 --- a/libavcodec/nvdec.c +++ b/libavcodec/nvdec.c @@ -295,7 +295,7 @@ int ff_nvdec_decode_init(AVCodecContext *avctx) av_log(avctx, AV_LOG_ERROR, "Unsupported chroma format\n"); return AVERROR(ENOSYS); } -chroma_444 = cuvid_chroma_format == cudaVideoChromaFormat_444; +chroma_444 = ctx->supports_444 && cuvid_chroma_format == cudaVideoChromaFormat_444; if (!avctx->hw_frames_ctx) { ret = ff_decode_get_hw_frames_ctx(avctx, AV_HWDEVICE_TYPE_CUDA); @@ -595,7 +595,8 @@ static AVBufferRef *nvdec_alloc_dummy(int size) int ff_nvdec_frame_params(AVCodecContext *avctx, AVBufferRef *hw_frames_ctx, - int dpb_size) + int dpb_size, + int supports_444) { AVHWFramesContext *frames_ctx = (AVHWFramesContext*)hw_frames_ctx->data; const AVPixFmtDescriptor *sw_desc; @@ -616,7 +617,7 @@ int ff_nvdec_frame_params(AVCodecContext *avctx, av_log(avctx, AV_LOG_VERBOSE, "Unsupported chroma format\n"); return AVERROR(EINVAL); } -chroma_444 = cuvid_chroma_format == cudaVideoChromaFormat_444; +chroma_444 = supports_444 && cuvid_chroma_format == cudaVideoChromaFormat_444; frames_ctx->format= AV_PIX_FMT_CUDA; frames_ctx->width = (avctx->coded_width + 1) & ~1; diff --git a/libavcodec/nvdec.h b/libavcodec/nvdec.h index 85a0fcf725..09ae8c37e6 100644 --- a/libavcodec/nvdec.h +++ b/libavcodec/nvdec.h @@ -61,6 +61,8 @@ typedef struct NVDECContext { unsigned *slice_offsets; int nb_slices; unsigned int slice_offsets_allocated; + +int supports_444; } NVDECContext; int ff_nvdec_decode_init(AVCodecContext *avctx); @@ -72,7 +74,8 @@ int ff_nvdec_simple_decode_slice(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size); int ff_nvdec_frame_params(AVCodecContext *avctx, AVBufferRef *hw_frames_ctx, - int dpb_size); + int dpb_size, + int supports_444); int ff_nvdec_get_ref_idx(AVFrame *frame); #endif /* AVCODEC_NVDEC_H */ diff --git a/libavcodec/nvdec_h264.c b/libavcodec/nvdec_h264.c index 25b30329d0..116bd4fb5d 100644 --- a/libavcodec/nvdec_h264.c +++ b/libavcodec/nvdec_h264.c @@ -166,7 +166,7 @@ static int nvdec_h264_frame_params(AVCodecContext *avctx, { const H264Context *h = avctx->priv_data; const SPS *sps = h->ps.sps; -return ff_nvdec_frame_params(avctx, hw_frames_ctx, sps->ref_frame_count + sps->num_reorder_frames); +return ff_nvdec_frame_params(avctx, hw_frames_ctx, sps->ref_frame_count + sps->num_reorder_frames, 0); } const AVHWAccel ff_h264_nvdec_hwaccel = { diff --git a/libavcodec/nvdec_hevc.c b/libavcodec/nvdec_hevc.c index e04a701f3a..9e726f708e 100644 --- a/libavcodec/nvdec_hevc.c +++ b/libavcodec/nvdec_hevc.c @@ -269,7 +269,13 @@ static int nvdec_hevc_frame_params(AVCodecContext *avctx, { const HEVCContext *s = avctx->priv_data; const HEVCSPS *sps = s->ps.sps; -return ff_nvdec_frame_params(avctx, hw_frames_ctx, sps->temporal_layer[sps->max_sub_layers - 1].max_dec_pic_buffering + 1); +return ff_nvdec_frame_params(avctx, hw_frames_ctx, sps->temporal_layer[sps->max_sub_layers - 1].max_dec_pic_buffering + 1, 1); +} + +static int nvdec_hevc_decode_init(AVCodecContext *avctx) { +NVDECContext *ctx = avctx->internal->hwaccel_priv_data; +ctx->supports_444 = 1; +return ff_nvdec_decode_init(avctx); } const AVHWAccel ff_hevc_nvdec_hwaccel = { @@ -281,7 +287,7 @@ const AVHWAccel ff_hevc_nvdec_hwaccel = { .end_frame= ff_nvdec_end_frame, .decode_slice = nvdec_hevc_decode_slice, .frame_params = nvdec_hevc_frame_params, -.init = ff_nvdec_decode_init, +.init = nvdec_hevc_decode_init, .uninit = ff_nvdec_decode_uninit, .priv_data_size = size
[FFmpeg-devel] [PATCH 2/5] avcodec/nvdec: Add support for decoding HEVC 4:4:4 content
The latest generation video decoder on the Turing chips supports decoding HEVC 4:4:4. Supporting this is relatively straight-forward; we need to account for the different chroma format and pick the right output and sw formats at the right times. There was one bug which was the hard-coded assumption that the first chroma plane would be half-height; I fixed this to use the actual shift value on the plane. The output formats ('2', and '3') are currently undocumented but appear to be YUV444P and YUV444P16 based on how they behave. Signed-off-by: Philip Langdale --- libavcodec/hevcdec.c | 3 +++ libavcodec/nvdec.c | 43 +++--- libavutil/hwcontext_cuda.c | 2 ++ 3 files changed, 40 insertions(+), 8 deletions(-) diff --git a/libavcodec/hevcdec.c b/libavcodec/hevcdec.c index a3b5c8cb71..972f2b56b6 100644 --- a/libavcodec/hevcdec.c +++ b/libavcodec/hevcdec.c @@ -409,6 +409,9 @@ static enum AVPixelFormat get_format(HEVCContext *s, const HEVCSPS *sps) #endif break; case AV_PIX_FMT_YUV420P12: +case AV_PIX_FMT_YUV444P: +case AV_PIX_FMT_YUV444P10: +case AV_PIX_FMT_YUV444P12: #if CONFIG_HEVC_NVDEC_HWACCEL *fmt++ = AV_PIX_FMT_CUDA; #endif diff --git a/libavcodec/nvdec.c b/libavcodec/nvdec.c index e779be3a45..e1ac06f852 100644 --- a/libavcodec/nvdec.c +++ b/libavcodec/nvdec.c @@ -34,6 +34,9 @@ #include "nvdec.h" #include "internal.h" +#define NVDEC_FORMAT_YUV444P 2 +#define NVDEC_FORMAT_YUV444P16 3 + typedef struct NVDECDecoder { CUvideodecoder decoder; @@ -273,7 +276,8 @@ int ff_nvdec_decode_init(AVCodecContext *avctx) CUVIDDECODECREATEINFO params = { 0 }; -int cuvid_codec_type, cuvid_chroma_format; +cudaVideoSurfaceFormat output_format; +int cuvid_codec_type, cuvid_chroma_format, chroma_444; int ret = 0; sw_desc = av_pix_fmt_desc_get(avctx->sw_pix_fmt); @@ -291,6 +295,7 @@ int ff_nvdec_decode_init(AVCodecContext *avctx) av_log(avctx, AV_LOG_ERROR, "Unsupported chroma format\n"); return AVERROR(ENOSYS); } +chroma_444 = cuvid_chroma_format == cudaVideoChromaFormat_444; if (!avctx->hw_frames_ctx) { ret = ff_decode_get_hw_frames_ctx(avctx, AV_HWDEVICE_TYPE_CUDA); @@ -298,6 +303,21 @@ int ff_nvdec_decode_init(AVCodecContext *avctx) return ret; } +switch (sw_desc->comp[0].depth) { +case 8: +output_format = chroma_444 ? NVDEC_FORMAT_YUV444P : + cudaVideoSurfaceFormat_NV12; +break; +case 10: +case 12: +output_format = chroma_444 ? NVDEC_FORMAT_YUV444P16 : + cudaVideoSurfaceFormat_P016; +break; +default: +av_log(avctx, AV_LOG_ERROR, "Unsupported bit depth\n"); +return AVERROR(ENOSYS); +} + frames_ctx = (AVHWFramesContext*)avctx->hw_frames_ctx->data; params.ulWidth = avctx->coded_width; @@ -305,8 +325,7 @@ int ff_nvdec_decode_init(AVCodecContext *avctx) params.ulTargetWidth = avctx->coded_width; params.ulTargetHeight = avctx->coded_height; params.bitDepthMinus8 = sw_desc->comp[0].depth - 8; -params.OutputFormat= params.bitDepthMinus8 ? - cudaVideoSurfaceFormat_P016 : cudaVideoSurfaceFormat_NV12; +params.OutputFormat= output_format; params.CodecType = cuvid_codec_type; params.ChromaFormat= cuvid_chroma_format; params.ulNumDecodeSurfaces = frames_ctx->initial_pool_size; @@ -388,6 +407,8 @@ static int nvdec_retrieve_data(void *logctx, AVFrame *frame) NVDECFrame*cf = (NVDECFrame*)fdd->hwaccel_priv; NVDECDecoder *decoder = (NVDECDecoder*)cf->decoder_ref->data; +AVHWFramesContext *hwctx = (AVHWFramesContext *)frame->hw_frames_ctx->data; + CUVIDPROCPARAMS vpp = { 0 }; NVDECFrame *unmap_data = NULL; @@ -397,6 +418,7 @@ static int nvdec_retrieve_data(void *logctx, AVFrame *frame) unsigned int pitch, i; unsigned int offset = 0; +int shift_h = 0, shift_v = 0; int ret = 0; vpp.progressive_frame = 1; @@ -433,10 +455,11 @@ static int nvdec_retrieve_data(void *logctx, AVFrame *frame) unmap_data->idx_ref = av_buffer_ref(cf->idx_ref); unmap_data->decoder_ref = av_buffer_ref(cf->decoder_ref); +av_pix_fmt_get_chroma_sub_sample(hwctx->sw_format, &shift_h, &shift_v); for (i = 0; frame->linesize[i]; i++) { frame->data[i] = (uint8_t*)(devptr + offset); frame->linesize[i] = pitch; -offset += pitch * (frame->height >> (i ? 1 : 0)); +offset += pitch * (frame->height >> (i ? shift_v : 0)); } goto finish; @@ -576,7 +599,7 @@ int ff_nvdec_frame_params(AVCodecContext *avctx, { AVHWFramesCont
[FFmpeg-devel] [PATCH 5/5] avcodec/nvenc: Accept YUV444P10_LSB and YUV444P12_LSB content
12bit is implicitly truncated to 10bit as part of doing this, but we already do that for P016 and YUV444P16. I've bundled a single version bump and changelog entry in this change to reflect the updates to all three of nvdec/nvenc/cuviddec. Signed-off-by: Philip Langdale --- Changelog| 1 + libavcodec/nvenc.c | 18 +- libavcodec/version.h | 2 +- 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/Changelog b/Changelog index 6c5e3c1c5d..12f600f8e6 100644 --- a/Changelog +++ b/Changelog @@ -33,6 +33,7 @@ version : - ilbc decoder - audio denoiser as afftdn filter - AV1 parser +- Support for HEVC 4:4:4 content in nvdec/nvenc/cuviddec version 4.0: diff --git a/libavcodec/nvenc.c b/libavcodec/nvenc.c index e180d7b993..74f3842a0b 100644 --- a/libavcodec/nvenc.c +++ b/libavcodec/nvenc.c @@ -41,8 +41,10 @@ const enum AVPixelFormat ff_nvenc_pix_fmts[] = { AV_PIX_FMT_NV12, AV_PIX_FMT_P010, AV_PIX_FMT_YUV444P, -AV_PIX_FMT_P016, // Truncated to 10bits -AV_PIX_FMT_YUV444P16, // Truncated to 10bits +AV_PIX_FMT_P016, // Truncated to 10bits +AV_PIX_FMT_YUV444P10_LSB, +AV_PIX_FMT_YUV444P12_LSB, // Truncated to 10bits +AV_PIX_FMT_YUV444P16, // Truncated to 10bits AV_PIX_FMT_0RGB32, AV_PIX_FMT_0BGR32, AV_PIX_FMT_CUDA, @@ -52,11 +54,15 @@ 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_P016|| \ +#define IS_10BIT(pix_fmt) (pix_fmt == AV_PIX_FMT_P010 || \ +pix_fmt == AV_PIX_FMT_P016 || \ +pix_fmt == AV_PIX_FMT_YUV444P10_LSB || \ +pix_fmt == AV_PIX_FMT_YUV444P12_LSB || \ pix_fmt == AV_PIX_FMT_YUV444P16) -#define IS_YUV444(pix_fmt) (pix_fmt == AV_PIX_FMT_YUV444P || \ +#define IS_YUV444(pix_fmt) (pix_fmt == AV_PIX_FMT_YUV444P || \ +pix_fmt == AV_PIX_FMT_YUV444P10_LSB || \ +pix_fmt == AV_PIX_FMT_YUV444P12_LSB || \ pix_fmt == AV_PIX_FMT_YUV444P16) static const struct { @@ -1263,6 +1269,8 @@ static NV_ENC_BUFFER_FORMAT nvenc_map_buffer_format(enum AVPixelFormat pix_fmt) return NV_ENC_BUFFER_FORMAT_YUV420_10BIT; case AV_PIX_FMT_YUV444P: return NV_ENC_BUFFER_FORMAT_YUV444_PL; +case AV_PIX_FMT_YUV444P10_LSB: +case AV_PIX_FMT_YUV444P12_LSB: case AV_PIX_FMT_YUV444P16: return NV_ENC_BUFFER_FORMAT_YUV444_10BIT; case AV_PIX_FMT_0RGB32: diff --git a/libavcodec/version.h b/libavcodec/version.h index 97d134851f..7e51585661 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -28,7 +28,7 @@ #include "libavutil/version.h" #define LIBAVCODEC_VERSION_MAJOR 58 -#define LIBAVCODEC_VERSION_MINOR 32 +#define LIBAVCODEC_VERSION_MINOR 33 #define LIBAVCODEC_VERSION_MICRO 100 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ -- 2.17.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH 4/5] avcodec/cuviddec: Add support for decoding HEVC 4:4:4 content
On Sun, 7 Oct 2018 10:50:56 -0700 Philip Langdale wrote: > This is the equivalent change for cuviddec after the previous change > for nvdec. I made similar changes to the copying routines to handle > pixel formats in a more generic way. > > Note that unlike with nvdec, there is no confusion about the ability > of a codec to output 444 formats. This is because the cuvid parser is > used, meaning that 444 JPEG content is still indicated as using a 420 > output format. > > Signed-off-by: Philip Langdale > --- > libavcodec/cuviddec.c | 59 > +-- 1 file changed, 40 > insertions(+), 19 deletions(-) > > diff --git a/libavcodec/cuviddec.c b/libavcodec/cuviddec.c > index 4d3caf924e..595249475d 100644 > --- a/libavcodec/cuviddec.c > +++ b/libavcodec/cuviddec.c > @@ -35,6 +35,9 @@ > #include "hwaccel.h" > #include "internal.h" > > +#define CUVID_FORMAT_YUV444P 2 > +#define CUVID_FORMAT_YUV444P16 3 > + > typedef struct CuvidContext > { > AVClass *avclass; > @@ -127,6 +130,7 @@ static int CUDAAPI > cuvid_handle_video_sequence(void *opaque, CUVIDEOFORMAT* form > CUVIDDECODECAPS *caps = NULL; CUVIDDECODECREATEINFO cuinfo; > int surface_fmt; > +int chroma_444; > > int old_width = avctx->width; > int old_height = avctx->height; > @@ -169,17 +173,19 @@ static int CUDAAPI > cuvid_handle_video_sequence(void *opaque, CUVIDEOFORMAT* form > cuinfo.target_rect.right = cuinfo.ulTargetWidth; > cuinfo.target_rect.bottom = cuinfo.ulTargetHeight; > +chroma_444 = format->chroma_format == cudaVideoChromaFormat_444; > + > switch (format->bit_depth_luma_minus8) { > case 0: // 8-bit > -pix_fmts[1] = AV_PIX_FMT_NV12; > +pix_fmts[1] = chroma_444 ? AV_PIX_FMT_YUV444P : > AV_PIX_FMT_NV12; caps = &ctx->caps8; > break; > case 2: // 10-bit > -pix_fmts[1] = AV_PIX_FMT_P010; > +pix_fmts[1] = chroma_444 ? AV_PIX_FMT_YUV444P10_LSB : > AV_PIX_FMT_P010; caps = &ctx->caps10; > break; > case 4: // 12-bit > -pix_fmts[1] = AV_PIX_FMT_P016; > +pix_fmts[1] = chroma_444 ? AV_PIX_FMT_YUV444P12_LSB : > AV_PIX_FMT_P016; caps = &ctx->caps12; > break; > default: > @@ -282,12 +288,6 @@ static int CUDAAPI > cuvid_handle_video_sequence(void *opaque, CUVIDEOFORMAT* form return > 0; } > > -if (format->chroma_format != cudaVideoChromaFormat_420) { > -av_log(avctx, AV_LOG_ERROR, "Chroma formats other than 420 > are not supported\n"); > -ctx->internal_error = AVERROR(EINVAL); > -return 0; > -} > - > ctx->chroma_format = format->chroma_format; > > cuinfo.CodecType = ctx->codec_type = format->codec; > @@ -301,6 +301,14 @@ static int CUDAAPI > cuvid_handle_video_sequence(void *opaque, CUVIDEOFORMAT* form case > AV_PIX_FMT_P016: cuinfo.OutputFormat = cudaVideoSurfaceFormat_P016; > break; > +case AV_PIX_FMT_YUV444P: > +cuinfo.OutputFormat = CUVID_FORMAT_YUV444P; > +break; > +case AV_PIX_FMT_YUV444P10_LSB: > +case AV_PIX_FMT_YUV444P12_LSB: > +case AV_PIX_FMT_YUV444P16: > +cuinfo.OutputFormat = CUVID_FORMAT_YUV444P16; > +break; > default: > av_log(avctx, AV_LOG_ERROR, "Output formats other than NV12, > P010 or P016 are not supported\n"); ctx->internal_error = > AVERROR(EINVAL); @@ -507,6 +515,7 @@ static int > cuvid_output_frame(AVCodecContext *avctx, AVFrame *frame) return ret; > > if (av_fifo_size(ctx->frame_queue)) { > +const AVPixFmtDescriptor *pixdesc; > CuvidParsedFrame parsed_frame; > CUVIDPROCPARAMS params; > unsigned int pitch = 0; > @@ -537,7 +546,10 @@ static int cuvid_output_frame(AVCodecContext > *avctx, AVFrame *frame) goto error; > } > > -for (i = 0; i < 2; i++) { > +pixdesc = av_pix_fmt_desc_get(avctx->sw_pix_fmt); > + > +for (i = 0; i < pixdesc->nb_components; i++) { > +size_t height = avctx->height >> (i ? > pixdesc->log2_chroma_h : 0); CUDA_MEMCPY2D cpy = { > .srcMemoryType = CU_MEMORYTYPE_DEVICE, > .dstMemoryType = CU_MEMORYTYPE_DEVICE, > @@ -547,22 +559,27 @@ static int cuvid_output_frame(AVCodecContext > *avctx, AVFrame *frame) .dstPitch = frame->linesize[i], > .srcY = offset, > .WidthInBytes = FFMIN(pitch, > frame->linesize[i]), > -.Height= avctx->height >
Re: [FFmpeg-devel] [PATCH 1/5] avutil: Add YUV444P10_LSB and YUV444P12_LSB pixel formats
On Mon, 8 Oct 2018 11:55:09 +0200 Hendrik Leppkes wrote: > On Mon, Oct 8, 2018 at 10:40 AM Timo Rothenpieler > wrote: > > > > > > I don't think it's YUVJ all over again, as it was the exact same bit > > layout than normal YUV, while this one is actually different. > > > > Its also the same bit layout as YUV444P16, with one piece of > additional metadata tacked on top - seems quite similar to YUVJ to me. So, this argument applies equally to P010 vs P016 doesn't it? Yet we all think P010 is a completely reasonable format to have, and in fact when I added it to cuvid/nvdec originally, I only did it as P016, and we all agreed that it should explicitly handle P010. I don't have a strong opinion on this one - I first wrote this patch as YUV444P16 as well and Timo asked for the explicit formats - but I think the consistency argument makes sense. And yes, I messed up the names. I renamed all to _MSB and have updated locally. Will repost after we're agreed on the principle. Thanks, --phil ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 2/5] avcodec/nvdec: Add support for decoding HEVC 4:4:4 content
The latest generation video decoder on the Turing chips supports decoding HEVC 4:4:4. Supporting this is relatively straight-forward; we need to account for the different chroma format and pick the right output and sw formats at the right times. There was one bug which was the hard-coded assumption that the first chroma plane would be half-height; I fixed this to use the actual shift value on the plane. The output formats ('2', and '3') are currently undocumented but appear to be YUV444P and YUV444P16 based on how they behave. Signed-off-by: Philip Langdale --- libavcodec/hevcdec.c | 3 +++ libavcodec/nvdec.c | 43 +++--- libavutil/hwcontext_cuda.c | 2 ++ 3 files changed, 40 insertions(+), 8 deletions(-) diff --git a/libavcodec/hevcdec.c b/libavcodec/hevcdec.c index a3b5c8cb71..972f2b56b6 100644 --- a/libavcodec/hevcdec.c +++ b/libavcodec/hevcdec.c @@ -409,6 +409,9 @@ static enum AVPixelFormat get_format(HEVCContext *s, const HEVCSPS *sps) #endif break; case AV_PIX_FMT_YUV420P12: +case AV_PIX_FMT_YUV444P: +case AV_PIX_FMT_YUV444P10: +case AV_PIX_FMT_YUV444P12: #if CONFIG_HEVC_NVDEC_HWACCEL *fmt++ = AV_PIX_FMT_CUDA; #endif diff --git a/libavcodec/nvdec.c b/libavcodec/nvdec.c index e779be3a45..43cc38485a 100644 --- a/libavcodec/nvdec.c +++ b/libavcodec/nvdec.c @@ -34,6 +34,9 @@ #include "nvdec.h" #include "internal.h" +#define NVDEC_FORMAT_YUV444P 2 +#define NVDEC_FORMAT_YUV444P16 3 + typedef struct NVDECDecoder { CUvideodecoder decoder; @@ -273,7 +276,8 @@ int ff_nvdec_decode_init(AVCodecContext *avctx) CUVIDDECODECREATEINFO params = { 0 }; -int cuvid_codec_type, cuvid_chroma_format; +cudaVideoSurfaceFormat output_format; +int cuvid_codec_type, cuvid_chroma_format, chroma_444; int ret = 0; sw_desc = av_pix_fmt_desc_get(avctx->sw_pix_fmt); @@ -291,6 +295,7 @@ int ff_nvdec_decode_init(AVCodecContext *avctx) av_log(avctx, AV_LOG_ERROR, "Unsupported chroma format\n"); return AVERROR(ENOSYS); } +chroma_444 = cuvid_chroma_format == cudaVideoChromaFormat_444; if (!avctx->hw_frames_ctx) { ret = ff_decode_get_hw_frames_ctx(avctx, AV_HWDEVICE_TYPE_CUDA); @@ -298,6 +303,21 @@ int ff_nvdec_decode_init(AVCodecContext *avctx) return ret; } +switch (sw_desc->comp[0].depth) { +case 8: +output_format = chroma_444 ? NVDEC_FORMAT_YUV444P : + cudaVideoSurfaceFormat_NV12; +break; +case 10: +case 12: +output_format = chroma_444 ? NVDEC_FORMAT_YUV444P16 : + cudaVideoSurfaceFormat_P016; +break; +default: +av_log(avctx, AV_LOG_ERROR, "Unsupported bit depth\n"); +return AVERROR(ENOSYS); +} + frames_ctx = (AVHWFramesContext*)avctx->hw_frames_ctx->data; params.ulWidth = avctx->coded_width; @@ -305,8 +325,7 @@ int ff_nvdec_decode_init(AVCodecContext *avctx) params.ulTargetWidth = avctx->coded_width; params.ulTargetHeight = avctx->coded_height; params.bitDepthMinus8 = sw_desc->comp[0].depth - 8; -params.OutputFormat= params.bitDepthMinus8 ? - cudaVideoSurfaceFormat_P016 : cudaVideoSurfaceFormat_NV12; +params.OutputFormat= output_format; params.CodecType = cuvid_codec_type; params.ChromaFormat= cuvid_chroma_format; params.ulNumDecodeSurfaces = frames_ctx->initial_pool_size; @@ -388,6 +407,8 @@ static int nvdec_retrieve_data(void *logctx, AVFrame *frame) NVDECFrame*cf = (NVDECFrame*)fdd->hwaccel_priv; NVDECDecoder *decoder = (NVDECDecoder*)cf->decoder_ref->data; +AVHWFramesContext *hwctx = (AVHWFramesContext *)frame->hw_frames_ctx->data; + CUVIDPROCPARAMS vpp = { 0 }; NVDECFrame *unmap_data = NULL; @@ -397,6 +418,7 @@ static int nvdec_retrieve_data(void *logctx, AVFrame *frame) unsigned int pitch, i; unsigned int offset = 0; +int shift_h = 0, shift_v = 0; int ret = 0; vpp.progressive_frame = 1; @@ -433,10 +455,11 @@ static int nvdec_retrieve_data(void *logctx, AVFrame *frame) unmap_data->idx_ref = av_buffer_ref(cf->idx_ref); unmap_data->decoder_ref = av_buffer_ref(cf->decoder_ref); +av_pix_fmt_get_chroma_sub_sample(hwctx->sw_format, &shift_h, &shift_v); for (i = 0; frame->linesize[i]; i++) { frame->data[i] = (uint8_t*)(devptr + offset); frame->linesize[i] = pitch; -offset += pitch * (frame->height >> (i ? 1 : 0)); +offset += pitch * (frame->height >> (i ? shift_v : 0)); } goto finish; @@ -576,7 +599,7 @@ int ff_nvdec_frame_params(AVCodecContext *avctx, { AVHWFramesCont
[FFmpeg-devel] [PATCH 4/5] avcodec/cuviddec: Add support for decoding HEVC 4:4:4 content
This is the equivalent change for cuviddec after the previous change for nvdec. I made similar changes to the copying routines to handle pixel formats in a more generic way. Note that unlike with nvdec, there is no confusion about the ability of a codec to output 444 formats. This is because the cuvid parser is used, meaning that 444 JPEG content is still indicated as using a 420 output format. Signed-off-by: Philip Langdale --- libavcodec/cuviddec.c | 59 +-- 1 file changed, 40 insertions(+), 19 deletions(-) diff --git a/libavcodec/cuviddec.c b/libavcodec/cuviddec.c index f21273c07e..ca9044353d 100644 --- a/libavcodec/cuviddec.c +++ b/libavcodec/cuviddec.c @@ -35,6 +35,9 @@ #include "hwaccel.h" #include "internal.h" +#define CUVID_FORMAT_YUV444P 2 +#define CUVID_FORMAT_YUV444P16 3 + typedef struct CuvidContext { AVClass *avclass; @@ -127,6 +130,7 @@ static int CUDAAPI cuvid_handle_video_sequence(void *opaque, CUVIDEOFORMAT* form CUVIDDECODECAPS *caps = NULL; CUVIDDECODECREATEINFO cuinfo; int surface_fmt; +int chroma_444; int old_width = avctx->width; int old_height = avctx->height; @@ -169,17 +173,19 @@ static int CUDAAPI cuvid_handle_video_sequence(void *opaque, CUVIDEOFORMAT* form cuinfo.target_rect.right = cuinfo.ulTargetWidth; cuinfo.target_rect.bottom = cuinfo.ulTargetHeight; +chroma_444 = format->chroma_format == cudaVideoChromaFormat_444; + switch (format->bit_depth_luma_minus8) { case 0: // 8-bit -pix_fmts[1] = AV_PIX_FMT_NV12; +pix_fmts[1] = chroma_444 ? AV_PIX_FMT_YUV444P : AV_PIX_FMT_NV12; caps = &ctx->caps8; break; case 2: // 10-bit -pix_fmts[1] = AV_PIX_FMT_P010; +pix_fmts[1] = chroma_444 ? AV_PIX_FMT_YUV444P10_MSB : AV_PIX_FMT_P010; caps = &ctx->caps10; break; case 4: // 12-bit -pix_fmts[1] = AV_PIX_FMT_P016; +pix_fmts[1] = chroma_444 ? AV_PIX_FMT_YUV444P12_MSB : AV_PIX_FMT_P016; caps = &ctx->caps12; break; default: @@ -282,12 +288,6 @@ static int CUDAAPI cuvid_handle_video_sequence(void *opaque, CUVIDEOFORMAT* form return 0; } -if (format->chroma_format != cudaVideoChromaFormat_420) { -av_log(avctx, AV_LOG_ERROR, "Chroma formats other than 420 are not supported\n"); -ctx->internal_error = AVERROR(EINVAL); -return 0; -} - ctx->chroma_format = format->chroma_format; cuinfo.CodecType = ctx->codec_type = format->codec; @@ -301,6 +301,14 @@ static int CUDAAPI cuvid_handle_video_sequence(void *opaque, CUVIDEOFORMAT* form case AV_PIX_FMT_P016: cuinfo.OutputFormat = cudaVideoSurfaceFormat_P016; break; +case AV_PIX_FMT_YUV444P: +cuinfo.OutputFormat = CUVID_FORMAT_YUV444P; +break; +case AV_PIX_FMT_YUV444P10_MSB: +case AV_PIX_FMT_YUV444P12_MSB: +case AV_PIX_FMT_YUV444P16: +cuinfo.OutputFormat = CUVID_FORMAT_YUV444P16; +break; default: av_log(avctx, AV_LOG_ERROR, "Output formats other than NV12, P010 or P016 are not supported\n"); ctx->internal_error = AVERROR(EINVAL); @@ -511,6 +519,7 @@ static int cuvid_output_frame(AVCodecContext *avctx, AVFrame *frame) return ret; if (av_fifo_size(ctx->frame_queue)) { +const AVPixFmtDescriptor *pixdesc; CuvidParsedFrame parsed_frame; CUVIDPROCPARAMS params; unsigned int pitch = 0; @@ -541,7 +550,10 @@ static int cuvid_output_frame(AVCodecContext *avctx, AVFrame *frame) goto error; } -for (i = 0; i < 2; i++) { +pixdesc = av_pix_fmt_desc_get(avctx->sw_pix_fmt); + +for (i = 0; i < pixdesc->nb_components; i++) { +size_t height = avctx->height >> (i ? pixdesc->log2_chroma_h : 0); CUDA_MEMCPY2D cpy = { .srcMemoryType = CU_MEMORYTYPE_DEVICE, .dstMemoryType = CU_MEMORYTYPE_DEVICE, @@ -551,22 +563,27 @@ static int cuvid_output_frame(AVCodecContext *avctx, AVFrame *frame) .dstPitch = frame->linesize[i], .srcY = offset, .WidthInBytes = FFMIN(pitch, frame->linesize[i]), -.Height= avctx->height >> (i ? 1 : 0), +.Height= height, }; ret = CHECK_CU(ctx->cudl->cuMemcpy2DAsync(&cpy, device_hwctx->stream)); if (ret < 0) goto error; -offset += avctx->height; +offset += height; } ret = CHECK_CU(ctx->cudl->cuStreamSynchronize(device_hwctx->stream)); if (ret < 0)
[FFmpeg-devel] [PATCH 5/5] avcodec/nvenc: Accept YUV444P10_MSB and YUV444P12_MSB content
12bit is implicitly truncated to 10bit as part of doing this, but we already do that for P016 and YUV444P16. I've bundled a single version bump and changelog entry in this change to reflect the updates to all three of nvdec/nvenc/cuviddec. Signed-off-by: Philip Langdale --- Changelog | 1 + libavcodec/nvenc.c | 18 +- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/Changelog b/Changelog index 1b0bc95b7a..1334eec474 100644 --- a/Changelog +++ b/Changelog @@ -35,6 +35,7 @@ version : - AV1 parser - SER demuxer - sinc audio filter source +- Support for HEVC 4:4:4 content in nvdec/nvenc/cuviddec version 4.0: diff --git a/libavcodec/nvenc.c b/libavcodec/nvenc.c index e180d7b993..5be98a5182 100644 --- a/libavcodec/nvenc.c +++ b/libavcodec/nvenc.c @@ -41,8 +41,10 @@ const enum AVPixelFormat ff_nvenc_pix_fmts[] = { AV_PIX_FMT_NV12, AV_PIX_FMT_P010, AV_PIX_FMT_YUV444P, -AV_PIX_FMT_P016, // Truncated to 10bits -AV_PIX_FMT_YUV444P16, // Truncated to 10bits +AV_PIX_FMT_P016, // Truncated to 10bits +AV_PIX_FMT_YUV444P10_MSB, +AV_PIX_FMT_YUV444P12_MSB, // Truncated to 10bits +AV_PIX_FMT_YUV444P16, // Truncated to 10bits AV_PIX_FMT_0RGB32, AV_PIX_FMT_0BGR32, AV_PIX_FMT_CUDA, @@ -52,11 +54,15 @@ 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_P016|| \ +#define IS_10BIT(pix_fmt) (pix_fmt == AV_PIX_FMT_P010 || \ +pix_fmt == AV_PIX_FMT_P016 || \ +pix_fmt == AV_PIX_FMT_YUV444P10_MSB || \ +pix_fmt == AV_PIX_FMT_YUV444P12_MSB || \ pix_fmt == AV_PIX_FMT_YUV444P16) -#define IS_YUV444(pix_fmt) (pix_fmt == AV_PIX_FMT_YUV444P || \ +#define IS_YUV444(pix_fmt) (pix_fmt == AV_PIX_FMT_YUV444P || \ +pix_fmt == AV_PIX_FMT_YUV444P10_MSB || \ +pix_fmt == AV_PIX_FMT_YUV444P12_MSB || \ pix_fmt == AV_PIX_FMT_YUV444P16) static const struct { @@ -1263,6 +1269,8 @@ static NV_ENC_BUFFER_FORMAT nvenc_map_buffer_format(enum AVPixelFormat pix_fmt) return NV_ENC_BUFFER_FORMAT_YUV420_10BIT; case AV_PIX_FMT_YUV444P: return NV_ENC_BUFFER_FORMAT_YUV444_PL; +case AV_PIX_FMT_YUV444P10_MSB: +case AV_PIX_FMT_YUV444P12_MSB: case AV_PIX_FMT_YUV444P16: return NV_ENC_BUFFER_FORMAT_YUV444_10BIT; case AV_PIX_FMT_0RGB32: -- 2.19.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 0/5] Add nvidia hw decode support for HEVC 4:4:4 content
The new video decoder hardware on Turing GPUs supports HEVC 4:4:4 content. This patch series adds the necessary new pixel formats and implements support in nvdec/nvenc/cuviddec. (Since the previous post of this series, I fixed the reversed terminology on the pixel formats) The big discussion was about the new pixel formats. I would like to get to a clear conclusion on this otherwise, this patch series goes nowhere forever, which I obviously don't want to happen, and I don't think is a legitmate outcome for reasonable functionality. So, discussion points: 1) What are the new data layouts that lack representation in the existing pixel formats? With the introduction of HEVC 444 support in the decoding hardware, we now have 3 plane YUV444 containing 10 or 12 bit data in an MSB packed format. MSB packing means the layout can be interpreted as 16 bit data transparently - equivalent to how P010 and P016 work. However, all the pre-existing formats are LSB packed so these layouts cannot be mapped to any of them except for YUV444P16, which is transparently compatible in the same way that P016 is. 2) Why would we just not use YUV444P16 for everything? The main reason is loss of metadata - after declaring that the data is stored as YUV444P16, we no longer know what the actual bith depth is. Using a format that explicitly declares the number of relevant bits preserves that, which may be beneficial for filtering or other transformations. 3) Why would we just not add these new formats and move on? There is a general reluctance to add new pixel formats without good reason, which is fair enough, but some people have also expressed a wish to decouple bit depth from pixel formats. This would mean carrying that information elsewhere and having the pixel format purely reflect the physical layout (ie: You'd only have P016 and YUV444P16). 4) Why not just implement this new mechanism for bit depth? Because it's a massive amount of work. Adding new metadata like this is a huge task that has impact throughout the codebase and also requires all clients to be rewritten at some point. A very close analog has been the attempt to remove YUVJ formats - these formats indicate the choice of a particular colourspace, with the same physical layout. Despite a lot of time and a lot of work, the YUVJ removal is still not done and it's been six months since the last patchset was proposed. There is no reason to believe that decoupling bit depth would not be a project of equal size and timescale - to say that this patchset is blocked on bit depth decoupling is to say that it's blocked indefinitely; no one even seriously articulated a desire to decouple bit depth until this patchset raised the issue, and no one has committed to doing the work. It's also unclear whether anyone would seriously suggest removing P010, which is an industry standard format - it would pointlessly harm interoperability with other tools and clients for ffmpeg to unilaterally declare that P010 was pointless and another mechanism should be used. Put another way, If YUV444P10_MSB was described in an MSDN document like P010, we'd probably not be having this conversation. (For the curious, MSDN only describes packed 444 formats.) 5) What about splitting the difference? One option that would reflect the relationship between P010 and P016 would be to only add YUV444P10_MSB and use YUV444P16 for 12 bit data. This means we add one format rather than two, and the usage of them is equivalent. Is that an interesting compromise? Doesn't bother me. 6) What does bother me? All I ultimately care about is getting this in. It's legimate hardware capability and I really want to make sure it's available. From that perspective I don't care if we add 0/1/2 formats - I will do whatever is agreed in the end. The option I am not happy with is saying that we can only expose the hardware capabilities if we implement bit depth decoupling - that's really saying you don't ever expect this functionality to go in. So, please, let's just make a decision. Philip Langdale (5): avutil: Add YUV444P10_MSB and YUV444P12_MSB pixel formats avcodec/nvdec: Add support for decoding HEVC 4:4:4 content avcodec/nvdec: Explicitly mark codecs that support 444 output formats avcodec/cuviddec: Add support for decoding HEVC 4:4:4 content avcodec/nvenc: Accept YUV444P10_MSB and YUV444P12_MSB content Changelog | 1 + libavcodec/cuviddec.c | 59 ++ libavcodec/hevcdec.c | 3 ++ libavcodec/nvdec.c | 46 +++-- libavcodec/nvdec.h | 5 +++- libavcodec/nvdec_h264.c| 2 +- libavcodec/nvdec_hevc.c| 10 +-- libavcodec/nvdec_mjpeg.c | 2 +- libavcodec/nvdec_mpeg12.c | 2 +- libavcodec/nvdec_mpeg4.c | 2 +- libavcodec/nvdec_vc1.c | 2 +- libavcodec/nvdec_vp8.c | 2 +- libavcodec/nvdec
[FFmpeg-devel] [PATCH 3/5] avcodec/nvdec: Explicitly mark codecs that support 444 output formats
With the introduction of HEVC 444 support, we technically have two codecs that can handle 444 - HEVC and MJPEG. In the case of MJPEG, it can decode, but can only output one of the semi-planar formats. That means we need additional logic to decide whether to use a 444 output format or not. Signed-off-by: Philip Langdale --- libavcodec/nvdec.c| 7 --- libavcodec/nvdec.h| 5 - libavcodec/nvdec_h264.c | 2 +- libavcodec/nvdec_hevc.c | 10 -- libavcodec/nvdec_mjpeg.c | 2 +- libavcodec/nvdec_mpeg12.c | 2 +- libavcodec/nvdec_mpeg4.c | 2 +- libavcodec/nvdec_vc1.c| 2 +- libavcodec/nvdec_vp8.c| 2 +- libavcodec/nvdec_vp9.c| 2 +- 10 files changed, 23 insertions(+), 13 deletions(-) diff --git a/libavcodec/nvdec.c b/libavcodec/nvdec.c index 43cc38485a..76e8b7c7bc 100644 --- a/libavcodec/nvdec.c +++ b/libavcodec/nvdec.c @@ -295,7 +295,7 @@ int ff_nvdec_decode_init(AVCodecContext *avctx) av_log(avctx, AV_LOG_ERROR, "Unsupported chroma format\n"); return AVERROR(ENOSYS); } -chroma_444 = cuvid_chroma_format == cudaVideoChromaFormat_444; +chroma_444 = ctx->supports_444 && cuvid_chroma_format == cudaVideoChromaFormat_444; if (!avctx->hw_frames_ctx) { ret = ff_decode_get_hw_frames_ctx(avctx, AV_HWDEVICE_TYPE_CUDA); @@ -595,7 +595,8 @@ static AVBufferRef *nvdec_alloc_dummy(int size) int ff_nvdec_frame_params(AVCodecContext *avctx, AVBufferRef *hw_frames_ctx, - int dpb_size) + int dpb_size, + int supports_444) { AVHWFramesContext *frames_ctx = (AVHWFramesContext*)hw_frames_ctx->data; const AVPixFmtDescriptor *sw_desc; @@ -616,7 +617,7 @@ int ff_nvdec_frame_params(AVCodecContext *avctx, av_log(avctx, AV_LOG_VERBOSE, "Unsupported chroma format\n"); return AVERROR(EINVAL); } -chroma_444 = cuvid_chroma_format == cudaVideoChromaFormat_444; +chroma_444 = supports_444 && cuvid_chroma_format == cudaVideoChromaFormat_444; frames_ctx->format= AV_PIX_FMT_CUDA; frames_ctx->width = (avctx->coded_width + 1) & ~1; diff --git a/libavcodec/nvdec.h b/libavcodec/nvdec.h index 85a0fcf725..09ae8c37e6 100644 --- a/libavcodec/nvdec.h +++ b/libavcodec/nvdec.h @@ -61,6 +61,8 @@ typedef struct NVDECContext { unsigned *slice_offsets; int nb_slices; unsigned int slice_offsets_allocated; + +int supports_444; } NVDECContext; int ff_nvdec_decode_init(AVCodecContext *avctx); @@ -72,7 +74,8 @@ int ff_nvdec_simple_decode_slice(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size); int ff_nvdec_frame_params(AVCodecContext *avctx, AVBufferRef *hw_frames_ctx, - int dpb_size); + int dpb_size, + int supports_444); int ff_nvdec_get_ref_idx(AVFrame *frame); #endif /* AVCODEC_NVDEC_H */ diff --git a/libavcodec/nvdec_h264.c b/libavcodec/nvdec_h264.c index 25b30329d0..116bd4fb5d 100644 --- a/libavcodec/nvdec_h264.c +++ b/libavcodec/nvdec_h264.c @@ -166,7 +166,7 @@ static int nvdec_h264_frame_params(AVCodecContext *avctx, { const H264Context *h = avctx->priv_data; const SPS *sps = h->ps.sps; -return ff_nvdec_frame_params(avctx, hw_frames_ctx, sps->ref_frame_count + sps->num_reorder_frames); +return ff_nvdec_frame_params(avctx, hw_frames_ctx, sps->ref_frame_count + sps->num_reorder_frames, 0); } const AVHWAccel ff_h264_nvdec_hwaccel = { diff --git a/libavcodec/nvdec_hevc.c b/libavcodec/nvdec_hevc.c index e04a701f3a..9e726f708e 100644 --- a/libavcodec/nvdec_hevc.c +++ b/libavcodec/nvdec_hevc.c @@ -269,7 +269,13 @@ static int nvdec_hevc_frame_params(AVCodecContext *avctx, { const HEVCContext *s = avctx->priv_data; const HEVCSPS *sps = s->ps.sps; -return ff_nvdec_frame_params(avctx, hw_frames_ctx, sps->temporal_layer[sps->max_sub_layers - 1].max_dec_pic_buffering + 1); +return ff_nvdec_frame_params(avctx, hw_frames_ctx, sps->temporal_layer[sps->max_sub_layers - 1].max_dec_pic_buffering + 1, 1); +} + +static int nvdec_hevc_decode_init(AVCodecContext *avctx) { +NVDECContext *ctx = avctx->internal->hwaccel_priv_data; +ctx->supports_444 = 1; +return ff_nvdec_decode_init(avctx); } const AVHWAccel ff_hevc_nvdec_hwaccel = { @@ -281,7 +287,7 @@ const AVHWAccel ff_hevc_nvdec_hwaccel = { .end_frame= ff_nvdec_end_frame, .decode_slice = nvdec_hevc_decode_slice, .frame_params = nvdec_hevc_frame_params, -.init = ff_nvdec_decode_init, +.init = nvdec_hevc_decode_init, .uninit = ff_nvdec_decode_uninit, .priv_data_size = size
[FFmpeg-devel] [PATCH 1/5] avutil: Add YUV444P10_MSB and YUV444P12_MSB pixel formats
Currently, ffmpeg defines a set of YUV444P formats for use where the bits-per-pixel are between 8 and 16 bits. In these formats, the bits are packed in the LSBs of the 16 bits of available storage. On the other hand, all the hardware vendors have defined their equivalent formats with the bits packed in the MSBs, which has the virtue of making the memory layouts compatible with being treated as full 16 bit values (which is also why P010 is defined this way). So, to be able to use these hardware compatible formats, we need definitions for them in ffmpeg. Right now, I need this for nvdec, but Vulkan also uses the same format definitions. Signed-off-by: Philip Langdale --- libavutil/pixdesc.c | 48 + libavutil/pixfmt.h | 8 libavutil/version.h | 4 ++-- 3 files changed, 58 insertions(+), 2 deletions(-) diff --git a/libavutil/pixdesc.c b/libavutil/pixdesc.c index 970a83214c..8b2f521c88 100644 --- a/libavutil/pixdesc.c +++ b/libavutil/pixdesc.c @@ -1629,6 +1629,54 @@ 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_YUV444P10LE_MSB] = { +.name = "yuv444p10lemsb", +.nb_components = 3, +.log2_chroma_w = 0, +.log2_chroma_h = 0, +.comp = { +{ 0, 2, 0, 6, 10, 1, 9, 1 },/* Y */ +{ 1, 2, 0, 6, 10, 1, 9, 1 },/* U */ +{ 2, 2, 0, 6, 10, 1, 9, 1 },/* V */ +}, +.flags = AV_PIX_FMT_FLAG_PLANAR, +}, +[AV_PIX_FMT_YUV444P10BE_MSB] = { +.name = "yuv444p10bemsb", +.nb_components = 3, +.log2_chroma_w = 0, +.log2_chroma_h = 0, +.comp = { +{ 0, 2, 0, 6, 10, 1, 9, 1 },/* Y */ +{ 1, 2, 0, 6, 10, 1, 9, 1 },/* U */ +{ 2, 2, 0, 6, 10, 1, 9, 1 },/* V */ +}, +.flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR, +}, +[AV_PIX_FMT_YUV444P12LE_MSB] = { +.name = "yuv444p12lemsb", +.nb_components = 3, +.log2_chroma_w = 0, +.log2_chroma_h = 0, +.comp = { +{ 0, 2, 0, 4, 12, 1, 11, 1 },/* Y */ +{ 1, 2, 0, 4, 12, 1, 11, 1 },/* U */ +{ 2, 2, 0, 4, 12, 1, 11, 1 },/* V */ +}, +.flags = AV_PIX_FMT_FLAG_PLANAR, +}, +[AV_PIX_FMT_YUV444P12BE_MSB] = { +.name = "yuv444p12bemsb", +.nb_components = 3, +.log2_chroma_w = 0, +.log2_chroma_h = 0, +.comp = { +{ 0, 2, 0, 4, 12, 1, 11, 1 },/* Y */ +{ 1, 2, 0, 4, 12, 1, 11, 1 },/* U */ +{ 2, 2, 0, 4, 12, 1, 11, 1 },/* V */ +}, +.flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR, +}, [AV_PIX_FMT_D3D11VA_VLD] = { .name = "d3d11va_vld", .log2_chroma_w = 1, diff --git a/libavutil/pixfmt.h b/libavutil/pixfmt.h index 6815f8dc7b..aaa7dcdb50 100644 --- a/libavutil/pixfmt.h +++ b/libavutil/pixfmt.h @@ -340,6 +340,11 @@ enum AVPixelFormat { AV_PIX_FMT_GRAYF32BE, ///< IEEE-754 single precision Y, 32bpp, big-endian AV_PIX_FMT_GRAYF32LE, ///< IEEE-754 single precision Y, 32bpp, little-endian +AV_PIX_FMT_YUV444P10LE_MSB, ///< planar YUV 4:4:4, 30bpp, (1 Cr & Cb sample per 1x1 Y samples), MSB packed, little-endian +AV_PIX_FMT_YUV444P10BE_MSB, ///< planar YUV 4:4:4, 30bpp, (1 Cr & Cb sample per 1x1 Y samples), MSB packed, big-endian +AV_PIX_FMT_YUV444P12LE_MSB, ///< planar YUV 4:4:4, 36bpp, (1 Cr & Cb sample per 1x1 Y samples), MSB packed, little-endian +AV_PIX_FMT_YUV444P12BE_MSB, ///< planar YUV 4:4:4, 36bpp, (1 Cr & Cb sample per 1x1 Y samples), MSB packed, big-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 }; @@ -391,6 +396,9 @@ enum AVPixelFormat { #define AV_PIX_FMT_YUV422P16 AV_PIX_FMT_NE(YUV422P16BE, YUV422P16LE) #define AV_PIX_FMT_YUV444P16 AV_PIX_FMT_NE(YUV444P16BE, YUV444P16LE) +#define AV_PIX_FMT_YUV444P10_MSB AV_PIX_FMT_NE(YUV444P10BE_MSB, YUV444P10LE_MSB) +#define AV_PIX_FMT_YUV444P12_MSB AV_PIX_FMT_NE(YUV444P12BE_MSB, YUV444P12LE_MSB) + #define AV_PIX_FMT_GBRP9 AV_PIX_FMT_NE(GBRP9BE ,GBRP9LE) #define AV_PIX_FMT_GBRP10AV_PIX_FMT_NE(GBRP10BE,GBRP10LE) #define AV_PIX_FMT_GBRP12AV_PIX_FMT_NE(GBRP12BE,GBRP12LE) diff --git a/libavutil/version.h b/libavutil/version.h index f84ec89154..377714a91e 100644 --- a/libavutil/version.h +++ b/libavutil/version.h @@ -79,8 +79,8 @@ */ #define LIBAVUTIL_VERSION_MAJOR 56 -#define LIBAVUTIL_VERSION_MINOR 19 -#define LIBAVUTIL_VERSION_MICRO 101 +#define LIBAVUTIL_VERSION_MINOR 20
Re: [FFmpeg-devel] [PATCH 2/5] avcodec/nvdec: Add support for decoding HEVC 4:4:4 content
On Sat, 20 Oct 2018 22:58:34 +0200 Timo Rothenpieler wrote: > > > > +// It it semantically incorrect to use AX_PIX_FMT_YUV444P16 > > for either the 10 > > +// or 12 bit case, but ffmpeg and nvidia disagree on which end > > the padding > > +// bits go at. P16 is unambiguous and matches. > > This comment seems redundant, since AX_PIX_FMT_YUV444P16 isn't even > used. Yeah, that's outdated from the original version with no pix fmts. I'll remove it. > > diff --git a/libavutil/hwcontext_cuda.c b/libavutil/hwcontext_cuda.c > > index 3b1d53e799..43337f14f0 100644 > > --- a/libavutil/hwcontext_cuda.c > > +++ b/libavutil/hwcontext_cuda.c > > @@ -38,6 +38,8 @@ static const enum AVPixelFormat > > supported_formats[] = { AV_PIX_FMT_YUV444P, > > AV_PIX_FMT_P010, > > AV_PIX_FMT_P016, > > +AV_PIX_FMT_YUV444P10_MSB, > > +AV_PIX_FMT_YUV444P12_MSB, > > You are adding these to supported formats, but are not actually > adding support, so cuda_frames_init and cuda_get_buffer will both run > into the BUG case. Should be super easy, as they're identical to > 444P16. This actually works fine. cuda_frames_init and cuda_get_buffer both use generic mechanisms that introspect the pix desc information. > > AV_PIX_FMT_YUV444P16, > Technically, this can go now. But I guess removing it is an API > break, so it gotta stay I guess. Right. And at the end of the day it works correctly in the context of the hwcontext. You might feed into some theoretical filter that would handle it appropriately. Just because nvenc can't actually consume it fully doesn't make it wrong. --phil ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH 4/5] avcodec/cuviddec: Add support for decoding HEVC 4:4:4 content
On Sat, 20 Oct 2018 23:10:57 +0200 Timo Rothenpieler wrote: > > > > -for (i = 0; i < 2; i++) { > > +pixdesc = av_pix_fmt_desc_get(avctx->sw_pix_fmt); > > + > > +for (i = 0; i < pixdesc->nb_components; i++) { > > +size_t height = avctx->height >> (i ? > > pixdesc->log2_chroma_h : 0); > > Is there a specific reason size_t is used here? It's the first use in > the entire file. Default habit from other projects. Fixed. > > +size_t offset = 0; > > Same here about size_t Also fixed. > > +for (i = 0; i < pixdesc->nb_components; i++) { > > +tmp_frame->data[i] = (uint8_t*)mapped_frame + > > offset; > > +tmp_frame->linesize[i] = pitch; > > I'd kinda like to have a comment here explaining that if YUV420P > would be used, pitch would need special handling, because it also > gets shifted there for the U/V planes. Added. Thanks, --phil ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 0/3] CUDA implementation of yadif filter
This patch series adds a CUDA implementation of yadif so that we have a deinterlacing option when doing full GPU transcode or playback with nvdec and/or nvenc. The nvidia deinterlacer cannot be used with the nvdec decoder because an hwaccel cannot return more than one frame per input packet. (It does work with the cuviddec decoder which is a full decoder, but uses nvidia's parsers which tend to be more limited than the ffmpeg ones). Philip Langdale (3): libavfilter/vf_yadif: Make frame management logic and options shareable avfilter/vf_yadif_cuda: CUDA accelerated deinterlacer avcodec/nvdec: Increase frame pool size to help deinterlacing Changelog| 1 + configure| 1 + doc/filters.texi | 58 + libavcodec/nvdec.c | 2 +- libavfilter/Makefile | 3 +- libavfilter/allfilters.c | 1 + libavfilter/version.h| 2 +- libavfilter/vf_yadif.c | 190 +--- libavfilter/vf_yadif_cuda.c | 426 +++ libavfilter/vf_yadif_cuda.cu | 296 libavfilter/yadif.h | 9 + libavfilter/yadif_common.c | 209 + 12 files changed, 1008 insertions(+), 190 deletions(-) create mode 100644 libavfilter/vf_yadif_cuda.c create mode 100644 libavfilter/vf_yadif_cuda.cu create mode 100644 libavfilter/yadif_common.c -- 2.19.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 1/3] libavfilter/vf_yadif: Make frame management logic and options shareable
I'm writing a cuda implementation of yadif, and while this obviously has a very different implementation of the actual filtering, all the frame management is unchanged. To avoid duplicating that logic, let's make it shareable. From the perspective of the existing filter, the only real change is introducing a function pointer for the filter() function so it can be specified for the specific filter. Signed-off-by: Philip Langdale --- libavfilter/Makefile | 2 +- libavfilter/vf_yadif.c | 190 + libavfilter/yadif.h| 9 ++ libavfilter/yadif_common.c | 209 + 4 files changed, 222 insertions(+), 188 deletions(-) create mode 100644 libavfilter/yadif_common.c diff --git a/libavfilter/Makefile b/libavfilter/Makefile index a98c64b7ce..6729b62b44 100644 --- a/libavfilter/Makefile +++ b/libavfilter/Makefile @@ -406,7 +406,7 @@ OBJS-$(CONFIG_WAVEFORM_FILTER) += vf_waveform.o OBJS-$(CONFIG_WEAVE_FILTER) += vf_weave.o OBJS-$(CONFIG_XBR_FILTER)+= vf_xbr.o OBJS-$(CONFIG_XSTACK_FILTER) += vf_stack.o framesync.o -OBJS-$(CONFIG_YADIF_FILTER) += vf_yadif.o +OBJS-$(CONFIG_YADIF_FILTER) += vf_yadif.o yadif_common.o OBJS-$(CONFIG_ZMQ_FILTER)+= f_zmq.o OBJS-$(CONFIG_ZOOMPAN_FILTER)+= vf_zoompan.o OBJS-$(CONFIG_ZSCALE_FILTER) += vf_zscale.o diff --git a/libavfilter/vf_yadif.c b/libavfilter/vf_yadif.c index f58d8ac2bc..1ff3ef6fb8 100644 --- a/libavfilter/vf_yadif.c +++ b/libavfilter/vf_yadif.c @@ -22,7 +22,6 @@ #include "libavutil/avassert.h" #include "libavutil/cpu.h" #include "libavutil/common.h" -#include "libavutil/opt.h" #include "libavutil/pixdesc.h" #include "libavutil/imgutils.h" #include "avfilter.h" @@ -254,166 +253,6 @@ static void filter(AVFilterContext *ctx, AVFrame *dstpic, emms_c(); } -static int return_frame(AVFilterContext *ctx, int is_second) -{ -YADIFContext *yadif = ctx->priv; -AVFilterLink *link = ctx->outputs[0]; -int tff, ret; - -if (yadif->parity == -1) { -tff = yadif->cur->interlaced_frame ? - yadif->cur->top_field_first : 1; -} else { -tff = yadif->parity ^ 1; -} - -if (is_second) { -yadif->out = ff_get_video_buffer(link, link->w, link->h); -if (!yadif->out) -return AVERROR(ENOMEM); - -av_frame_copy_props(yadif->out, yadif->cur); -yadif->out->interlaced_frame = 0; -} - -filter(ctx, yadif->out, tff ^ !is_second, tff); - -if (is_second) { -int64_t cur_pts = yadif->cur->pts; -int64_t next_pts = yadif->next->pts; - -if (next_pts != AV_NOPTS_VALUE && cur_pts != AV_NOPTS_VALUE) { -yadif->out->pts = cur_pts + next_pts; -} else { -yadif->out->pts = AV_NOPTS_VALUE; -} -} -ret = ff_filter_frame(ctx->outputs[0], yadif->out); - -yadif->frame_pending = (yadif->mode&1) && !is_second; -return ret; -} - -static int checkstride(YADIFContext *yadif, const AVFrame *a, const AVFrame *b) -{ -int i; -for (i = 0; i < yadif->csp->nb_components; i++) -if (a->linesize[i] != b->linesize[i]) -return 1; -return 0; -} - -static void fixstride(AVFilterLink *link, AVFrame *f) -{ -AVFrame *dst = ff_default_get_video_buffer(link, f->width, f->height); -if(!dst) -return; -av_frame_copy_props(dst, f); -av_image_copy(dst->data, dst->linesize, - (const uint8_t **)f->data, f->linesize, - dst->format, dst->width, dst->height); -av_frame_unref(f); -av_frame_move_ref(f, dst); -av_frame_free(&dst); -} - -static int filter_frame(AVFilterLink *link, AVFrame *frame) -{ -AVFilterContext *ctx = link->dst; -YADIFContext *yadif = ctx->priv; - -av_assert0(frame); - -if (yadif->frame_pending) -return_frame(ctx, 1); - -if (yadif->prev) -av_frame_free(&yadif->prev); -yadif->prev = yadif->cur; -yadif->cur = yadif->next; -yadif->next = frame; - -if (!yadif->cur && -!(yadif->cur = av_frame_clone(yadif->next))) -return AVERROR(ENOMEM); - -if (checkstride(yadif, yadif->next, yadif->cur)) { -av_log(ctx, AV_LOG_VERBOSE, "Reallocating frame due to differing stride\n"); -fixstride(link, yadif->next); -} -if (checkstride(yadif, yadif->next, yadif->cur)) -fixstride(link, yadif->cur); -if (yadif->prev && checkstride(yadif, yadif->next, yadif->prev)) -fixstride(link, yad
[FFmpeg-devel] [PATCH 3/3] avcodec/nvdec: Increase frame pool size to help deinterlacing
With the cuda yadif filter in use, the number of mapped decoder frames could increase by two, as the filter holds on to additional frames. Signed-off-by: Philip Langdale --- libavcodec/nvdec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/nvdec.c b/libavcodec/nvdec.c index 4dd6b1acf3..8e91c36084 100644 --- a/libavcodec/nvdec.c +++ b/libavcodec/nvdec.c @@ -601,7 +601,7 @@ int ff_nvdec_frame_params(AVCodecContext *avctx, frames_ctx->format= AV_PIX_FMT_CUDA; frames_ctx->width = (avctx->coded_width + 1) & ~1; frames_ctx->height= (avctx->coded_height + 1) & ~1; -frames_ctx->initial_pool_size = dpb_size; +frames_ctx->initial_pool_size = dpb_size + 2; frames_ctx->free = nvdec_free_dummy; frames_ctx->pool = av_buffer_pool_init(0, nvdec_alloc_dummy); -- 2.19.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 2/3] avfilter/vf_yadif_cuda: CUDA accelerated deinterlacer
Signed-off-by: Philip Langdale --- Changelog| 1 + configure| 1 + doc/filters.texi | 58 + libavfilter/Makefile | 1 + libavfilter/allfilters.c | 1 + libavfilter/version.h| 2 +- libavfilter/vf_yadif_cuda.c | 426 +++ libavfilter/vf_yadif_cuda.cu | 296 8 files changed, 785 insertions(+), 1 deletion(-) create mode 100644 libavfilter/vf_yadif_cuda.c create mode 100644 libavfilter/vf_yadif_cuda.cu diff --git a/Changelog b/Changelog index de0383047e..5c053503b5 100644 --- a/Changelog +++ b/Changelog @@ -41,6 +41,7 @@ version : - decoding S12M timecode in h264 - xstack filter - pcm vidc decoder and encoder +- yadif_cuda filter version 4.0: diff --git a/configure b/configure index 01c3a1011d..5a5d0b0868 100755 --- a/configure +++ b/configure @@ -3481,6 +3481,7 @@ zscale_filter_deps="libzimg const_nan" scale_vaapi_filter_deps="vaapi" vpp_qsv_filter_deps="libmfx" vpp_qsv_filter_select="qsvvpp" +yadif_cuda_filter_deps="cuda_sdk" # examples avio_dir_cmd_deps="avformat avutil" diff --git a/doc/filters.texi b/doc/filters.texi index 7811c25ddb..41da25081a 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -17862,6 +17862,64 @@ filter"). It accepts the following parameters: +@table @option + +@item mode +The interlacing mode to adopt. It accepts one of the following values: + +@table @option +@item 0, send_frame +Output one frame for each frame. +@item 1, send_field +Output one frame for each field. +@item 2, send_frame_nospatial +Like @code{send_frame}, but it skips the spatial interlacing check. +@item 3, send_field_nospatial +Like @code{send_field}, but it skips the spatial interlacing check. +@end table + +The default value is @code{send_frame}. + +@item parity +The picture field parity assumed for the input interlaced video. It accepts one +of the following values: + +@table @option +@item 0, tff +Assume the top field is first. +@item 1, bff +Assume the bottom field is first. +@item -1, auto +Enable automatic detection of field parity. +@end table + +The default value is @code{auto}. +If the interlacing is unknown or the decoder does not export this information, +top field first will be assumed. + +@item deint +Specify which frames to deinterlace. Accept one of the following +values: + +@table @option +@item 0, all +Deinterlace all frames. +@item 1, interlaced +Only deinterlace frames marked as interlaced. +@end table + +The default value is @code{all}. +@end table + +@section yadif_cuda + +Deinterlace the input video using the @ref{yadif} algorithm, but implemented +in CUDA so that it can work as part of a GPU accelerated pipeline with nvdec +and/or nvenc. + +It accepts the following parameters: + + @table @option @item mode diff --git a/libavfilter/Makefile b/libavfilter/Makefile index 6729b62b44..d2957c6403 100644 --- a/libavfilter/Makefile +++ b/libavfilter/Makefile @@ -407,6 +407,7 @@ OBJS-$(CONFIG_WEAVE_FILTER) += vf_weave.o OBJS-$(CONFIG_XBR_FILTER)+= vf_xbr.o OBJS-$(CONFIG_XSTACK_FILTER) += vf_stack.o framesync.o OBJS-$(CONFIG_YADIF_FILTER) += vf_yadif.o yadif_common.o +OBJS-$(CONFIG_YADIF_CUDA_FILTER) += vf_yadif_cuda.o vf_yadif_cuda.ptx.o yadif_common.o OBJS-$(CONFIG_ZMQ_FILTER)+= f_zmq.o OBJS-$(CONFIG_ZOOMPAN_FILTER)+= vf_zoompan.o OBJS-$(CONFIG_ZSCALE_FILTER) += vf_zscale.o diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c index b2cb58fc38..daabb2aa65 100644 --- a/libavfilter/allfilters.c +++ b/libavfilter/allfilters.c @@ -388,6 +388,7 @@ extern AVFilter ff_vf_weave; extern AVFilter ff_vf_xbr; extern AVFilter ff_vf_xstack; extern AVFilter ff_vf_yadif; +extern AVFilter ff_vf_yadif_cuda; extern AVFilter ff_vf_zmq; extern AVFilter ff_vf_zoompan; extern AVFilter ff_vf_zscale; diff --git a/libavfilter/version.h b/libavfilter/version.h index 77e1a77b50..e2572d623e 100644 --- a/libavfilter/version.h +++ b/libavfilter/version.h @@ -30,7 +30,7 @@ #include "libavutil/version.h" #define LIBAVFILTER_VERSION_MAJOR 7 -#define LIBAVFILTER_VERSION_MINOR 38 +#define LIBAVFILTER_VERSION_MINOR 39 #define LIBAVFILTER_VERSION_MICRO 100 #define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \ diff --git a/libavfilter/vf_yadif_cuda.c b/libavfilter/vf_yadif_cuda.c new file mode 100644 index 00..728b33076b --- /dev/null +++ b/libavfilter/vf_yadif_cuda.c @@ -0,0 +1,426 @@ +/* + * Copyright (C) 2018 Philip Langdale + * + * 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 (a
Re: [FFmpeg-devel] [PATCH 1/3] libavfilter/vf_yadif: Make frame management logic and options shareable
On 2018-11-01 12:42, Michael Niedermayer wrote: +const AVOption yadif_options[] = { missing prefix I will fix. Are you otherwise happy with this change? Thanks, --phil ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH 2/3] avfilter/vf_yadif_cuda: CUDA accelerated deinterlacer
On 2018-11-01 14:05, Timo Rothenpieler wrote: On 01.11.2018 21:54, Carl Eugen Hoyos wrote: 2018-10-26 17:56 GMT+02:00, Philip Langdale : Could you add some sample numbers about how fast the cuda variant is compared to cpu? I don't think such numbers are overly useful by themselves. The primary benefit here is that it's now possible to decode, deinterlace and encode all without pulling the frames out of VRAM. Though it would definitely be interesting. I guess hwupload + yadif_cuda + hwdownload vs. normal yadif is a fair comparison? Yeah, the comparison is a bit fuzzy, because you completely change how you think about solving the problem depending on whether you have a filter available or not. But I did get some data previously. For cpu decode + cpu yadif, the yadif slowdown is ~50% For gpu decode + gpu yadif, the yadif slowdown is ~25% That means, the fps reported by `ffmpeg` when down by 50%/25% respectively. This was with null encoding. I can collect data for the up/down case, but I do think it's unrealistic - no one would actually do that. --phil ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH 2/3] avfilter/vf_yadif_cuda: CUDA accelerated deinterlacer
On Thu, 1 Nov 2018 22:16:53 +0100 Hendrik Leppkes wrote: > One might do something like this: > > NVDEC -> hwdownload -> yadif -> x264 > NVDEC -> cuda_yadif -> hwdownload -> x264 > > How do those compare, maybe when you replace x264 with null? I set my baseline with NVDEC -> hwdownload -> null. I then compared hwdownload->yadif and cuda_yadif->hwdownload with same_frame and same_field. * hwdownload->yadif=same_frame: 70% * hwdownload->yadif=same_field: 56% * cuda_yadif=same_frame->hwdownload: 88% * cuda_yadif=same_field->hwdownload: 69% --phil ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 0/3] CUDA implementation of yadif filter v2
This patch series adds a CUDA implementation of yadif so that we have a deinterlacing option when doing full GPU transcode or playback with nvdec and/or nvenc. The nvidia deinterlacer cannot be used with the nvdec decoder because an hwaccel cannot return more than one frame per input packet. (It does work with the cuviddec decoder which is a full decoder, but uses nvidia's parsers which tend to be more limited than the ffmpeg ones). This update includes minor changes to reflect feedback. I will bump the minor version when I push. Philip Langdale (3): libavfilter/vf_yadif: Make frame management logic and options shareable avfilter/vf_yadif_cuda: CUDA accelerated deinterlacer avcodec/nvdec: Increase frame pool size to help deinterlacing Changelog| 1 + configure| 1 + doc/filters.texi | 58 + libavcodec/nvdec.c | 6 +- libavfilter/Makefile | 3 +- libavfilter/allfilters.c | 1 + libavfilter/vf_yadif.c | 196 +--- libavfilter/vf_yadif_cuda.c | 426 +++ libavfilter/vf_yadif_cuda.cu | 296 libavfilter/yadif.h | 9 + libavfilter/yadif_common.c | 209 + 11 files changed, 1017 insertions(+), 189 deletions(-) create mode 100644 libavfilter/vf_yadif_cuda.c create mode 100644 libavfilter/vf_yadif_cuda.cu create mode 100644 libavfilter/yadif_common.c -- 2.19.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 1/3] libavfilter/vf_yadif: Make frame management logic and options shareable
I'm writing a cuda implementation of yadif, and while this obviously has a very different implementation of the actual filtering, all the frame management is unchanged. To avoid duplicating that logic, let's make it shareable. From the perspective of the existing filter, the only real change is introducing a function pointer for the filter() function so it can be specified for the specific filter. Signed-off-by: Philip Langdale --- libavfilter/Makefile | 2 +- libavfilter/vf_yadif.c | 196 ++ libavfilter/yadif.h| 9 ++ libavfilter/yadif_common.c | 209 + 4 files changed, 228 insertions(+), 188 deletions(-) create mode 100644 libavfilter/yadif_common.c diff --git a/libavfilter/Makefile b/libavfilter/Makefile index c35cd8f422..ffbcb40806 100644 --- a/libavfilter/Makefile +++ b/libavfilter/Makefile @@ -407,7 +407,7 @@ OBJS-$(CONFIG_WAVEFORM_FILTER) += vf_waveform.o OBJS-$(CONFIG_WEAVE_FILTER) += vf_weave.o OBJS-$(CONFIG_XBR_FILTER)+= vf_xbr.o OBJS-$(CONFIG_XSTACK_FILTER) += vf_stack.o framesync.o -OBJS-$(CONFIG_YADIF_FILTER) += vf_yadif.o +OBJS-$(CONFIG_YADIF_FILTER) += vf_yadif.o yadif_common.o OBJS-$(CONFIG_ZMQ_FILTER)+= f_zmq.o OBJS-$(CONFIG_ZOOMPAN_FILTER)+= vf_zoompan.o OBJS-$(CONFIG_ZSCALE_FILTER) += vf_zscale.o diff --git a/libavfilter/vf_yadif.c b/libavfilter/vf_yadif.c index f58d8ac2bc..3107924932 100644 --- a/libavfilter/vf_yadif.c +++ b/libavfilter/vf_yadif.c @@ -22,7 +22,6 @@ #include "libavutil/avassert.h" #include "libavutil/cpu.h" #include "libavutil/common.h" -#include "libavutil/opt.h" #include "libavutil/pixdesc.h" #include "libavutil/imgutils.h" #include "avfilter.h" @@ -254,166 +253,6 @@ static void filter(AVFilterContext *ctx, AVFrame *dstpic, emms_c(); } -static int return_frame(AVFilterContext *ctx, int is_second) -{ -YADIFContext *yadif = ctx->priv; -AVFilterLink *link = ctx->outputs[0]; -int tff, ret; - -if (yadif->parity == -1) { -tff = yadif->cur->interlaced_frame ? - yadif->cur->top_field_first : 1; -} else { -tff = yadif->parity ^ 1; -} - -if (is_second) { -yadif->out = ff_get_video_buffer(link, link->w, link->h); -if (!yadif->out) -return AVERROR(ENOMEM); - -av_frame_copy_props(yadif->out, yadif->cur); -yadif->out->interlaced_frame = 0; -} - -filter(ctx, yadif->out, tff ^ !is_second, tff); - -if (is_second) { -int64_t cur_pts = yadif->cur->pts; -int64_t next_pts = yadif->next->pts; - -if (next_pts != AV_NOPTS_VALUE && cur_pts != AV_NOPTS_VALUE) { -yadif->out->pts = cur_pts + next_pts; -} else { -yadif->out->pts = AV_NOPTS_VALUE; -} -} -ret = ff_filter_frame(ctx->outputs[0], yadif->out); - -yadif->frame_pending = (yadif->mode&1) && !is_second; -return ret; -} - -static int checkstride(YADIFContext *yadif, const AVFrame *a, const AVFrame *b) -{ -int i; -for (i = 0; i < yadif->csp->nb_components; i++) -if (a->linesize[i] != b->linesize[i]) -return 1; -return 0; -} - -static void fixstride(AVFilterLink *link, AVFrame *f) -{ -AVFrame *dst = ff_default_get_video_buffer(link, f->width, f->height); -if(!dst) -return; -av_frame_copy_props(dst, f); -av_image_copy(dst->data, dst->linesize, - (const uint8_t **)f->data, f->linesize, - dst->format, dst->width, dst->height); -av_frame_unref(f); -av_frame_move_ref(f, dst); -av_frame_free(&dst); -} - -static int filter_frame(AVFilterLink *link, AVFrame *frame) -{ -AVFilterContext *ctx = link->dst; -YADIFContext *yadif = ctx->priv; - -av_assert0(frame); - -if (yadif->frame_pending) -return_frame(ctx, 1); - -if (yadif->prev) -av_frame_free(&yadif->prev); -yadif->prev = yadif->cur; -yadif->cur = yadif->next; -yadif->next = frame; - -if (!yadif->cur && -!(yadif->cur = av_frame_clone(yadif->next))) -return AVERROR(ENOMEM); - -if (checkstride(yadif, yadif->next, yadif->cur)) { -av_log(ctx, AV_LOG_VERBOSE, "Reallocating frame due to differing stride\n"); -fixstride(link, yadif->next); -} -if (checkstride(yadif, yadif->next, yadif->cur)) -fixstride(link, yadif->cur); -if (yadif->prev && checkstride(yadif, yadif->next, yadif->prev)) -fixstride(link, yad
[FFmpeg-devel] [PATCH 3/3] avcodec/nvdec: Increase frame pool size to help deinterlacing
With the cuda yadif filter in use, the number of mapped decoder frames could increase by two, as the filter holds on to additional frames. Signed-off-by: Philip Langdale --- libavcodec/nvdec.c | 6 +- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/libavcodec/nvdec.c b/libavcodec/nvdec.c index 4dd6b1acf3..0426c9b319 100644 --- a/libavcodec/nvdec.c +++ b/libavcodec/nvdec.c @@ -601,7 +601,11 @@ int ff_nvdec_frame_params(AVCodecContext *avctx, frames_ctx->format= AV_PIX_FMT_CUDA; frames_ctx->width = (avctx->coded_width + 1) & ~1; frames_ctx->height= (avctx->coded_height + 1) & ~1; -frames_ctx->initial_pool_size = dpb_size; +/* + * We add two extra frames to the pool to account for deinterlacing filters + * holding onto their frames. + */ +frames_ctx->initial_pool_size = dpb_size + 2; frames_ctx->free = nvdec_free_dummy; frames_ctx->pool = av_buffer_pool_init(0, nvdec_alloc_dummy); -- 2.19.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 2/3] avfilter/vf_yadif_cuda: CUDA accelerated deinterlacer
Signed-off-by: Philip Langdale --- Changelog| 1 + configure| 1 + doc/filters.texi | 58 + libavfilter/Makefile | 1 + libavfilter/allfilters.c | 1 + libavfilter/vf_yadif_cuda.c | 426 +++ libavfilter/vf_yadif_cuda.cu | 296 7 files changed, 784 insertions(+) create mode 100644 libavfilter/vf_yadif_cuda.c create mode 100644 libavfilter/vf_yadif_cuda.cu diff --git a/Changelog b/Changelog index 8430da3c6a..f92886fc2e 100644 --- a/Changelog +++ b/Changelog @@ -44,6 +44,7 @@ version 4.1: - xstack filter - pcm vidc decoder and encoder - (a)graphmonitor filter +- yadif_cuda filter version 4.0: diff --git a/configure b/configure index 2606b885b0..f3fa0cde86 100755 --- a/configure +++ b/configure @@ -3482,6 +3482,7 @@ zscale_filter_deps="libzimg const_nan" scale_vaapi_filter_deps="vaapi" vpp_qsv_filter_deps="libmfx" vpp_qsv_filter_select="qsvvpp" +yadif_cuda_filter_deps="cuda_sdk" # examples avio_dir_cmd_deps="avformat avutil" diff --git a/doc/filters.texi b/doc/filters.texi index 4345a4931b..5d4bfd2e8e 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -17943,6 +17943,64 @@ filter"). It accepts the following parameters: +@table @option + +@item mode +The interlacing mode to adopt. It accepts one of the following values: + +@table @option +@item 0, send_frame +Output one frame for each frame. +@item 1, send_field +Output one frame for each field. +@item 2, send_frame_nospatial +Like @code{send_frame}, but it skips the spatial interlacing check. +@item 3, send_field_nospatial +Like @code{send_field}, but it skips the spatial interlacing check. +@end table + +The default value is @code{send_frame}. + +@item parity +The picture field parity assumed for the input interlaced video. It accepts one +of the following values: + +@table @option +@item 0, tff +Assume the top field is first. +@item 1, bff +Assume the bottom field is first. +@item -1, auto +Enable automatic detection of field parity. +@end table + +The default value is @code{auto}. +If the interlacing is unknown or the decoder does not export this information, +top field first will be assumed. + +@item deint +Specify which frames to deinterlace. Accept one of the following +values: + +@table @option +@item 0, all +Deinterlace all frames. +@item 1, interlaced +Only deinterlace frames marked as interlaced. +@end table + +The default value is @code{all}. +@end table + +@section yadif_cuda + +Deinterlace the input video using the @ref{yadif} algorithm, but implemented +in CUDA so that it can work as part of a GPU accelerated pipeline with nvdec +and/or nvenc. + +It accepts the following parameters: + + @table @option @item mode diff --git a/libavfilter/Makefile b/libavfilter/Makefile index ffbcb40806..4b78b29fad 100644 --- a/libavfilter/Makefile +++ b/libavfilter/Makefile @@ -408,6 +408,7 @@ OBJS-$(CONFIG_WEAVE_FILTER) += vf_weave.o OBJS-$(CONFIG_XBR_FILTER)+= vf_xbr.o OBJS-$(CONFIG_XSTACK_FILTER) += vf_stack.o framesync.o OBJS-$(CONFIG_YADIF_FILTER) += vf_yadif.o yadif_common.o +OBJS-$(CONFIG_YADIF_CUDA_FILTER) += vf_yadif_cuda.o vf_yadif_cuda.ptx.o yadif_common.o OBJS-$(CONFIG_ZMQ_FILTER)+= f_zmq.o OBJS-$(CONFIG_ZOOMPAN_FILTER)+= vf_zoompan.o OBJS-$(CONFIG_ZSCALE_FILTER) += vf_zscale.o diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c index d5a211bda5..c40c7e3a3c 100644 --- a/libavfilter/allfilters.c +++ b/libavfilter/allfilters.c @@ -389,6 +389,7 @@ extern AVFilter ff_vf_weave; extern AVFilter ff_vf_xbr; extern AVFilter ff_vf_xstack; extern AVFilter ff_vf_yadif; +extern AVFilter ff_vf_yadif_cuda; extern AVFilter ff_vf_zmq; extern AVFilter ff_vf_zoompan; extern AVFilter ff_vf_zscale; diff --git a/libavfilter/vf_yadif_cuda.c b/libavfilter/vf_yadif_cuda.c new file mode 100644 index 00..be22344d9d --- /dev/null +++ b/libavfilter/vf_yadif_cuda.c @@ -0,0 +1,426 @@ +/* + * Copyright (C) 2018 Philip Langdale + * + * 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
Re: [FFmpeg-devel] [PATCH] Add CUDA function cuDeviceGetAttribute
On Thu, 1 Nov 2018 23:48:03 + Soft Works wrote: > In this context, I wonder if there is some explanation somewhere > about the differences between the cuvid and nvdec codec > implementations. > > I understand the ffmpeg side where cuvid is a full codec and nvdec is > implemented as hwaccel. This is correct. It's the same decoder being used, but 'cuviddec' uses the full nvidia parser, which then drives the decoder. As such, it's a full codec. nvdec is an hwaccel that plugs into the ffmpeg decoders. > What adds to the confusion is that the hwaccel is called 'cuda'. The hwaccels are officially called 'cuvid' and 'nvdec'. As a convenience, we alias 'cuda' to 'nvdec'. The confusion is that the HW pix_fmt and hwcontext are called 'cuda' because these are generic and used by both decoders (and the various cuda based filters). > > What I'm wondering now is what difference all this makes at the side > of the GPU acceleration, doesn't this end up being just the same? > Why do we have that dual implementation? We have two primarily because cuviddec was written first, as it's relatively easy to build a working full codec around the nvidia library and it supports all the formats largely automatically. Writing an hwaccel is a bit more work, including the very tedious exercise of mapping all the properties across when describing a frame for the decoder. But it was eventually done. Now, cuviddec has somewhat limited value. It allows you to take advantage of the nvidia deinterlacer, which does rate doubling. This can't be used in nvdec because an hwaccel can't change the frame rate. It may be more performant in certain situations. But apart from those two things, you should use nvdec. The ffmpeg parsers and decoders are generally more capable than the nvidia ones, and particularly for HDR content, the nvidia ones have problems. I've made an attempt to bridge the deinterlacing gap by writing a yadif_cuda deinterlacer as you've probably seen on the list, but I suspect cuviddec will stick around just because it might be a useful option for some people. --phil ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 0/2] Update vf_bwdif to use yadif_common
vf_bwdif's frame management logic is almost identical to that of yadif. The only difference is that it tracks the first and last fields in a sequence, and that requires slight changes to the common code. Assuming it's reasonable to do that tracking even though yadif doesn't need it, we can then remove all the duplicated logic. Philip Langdale (2): avfilter/yadif_common: Add field type tracking to help bwdif avfilter/vf_bwdif: Use common yadif frame management logic libavfilter/bwdif.h | 34 + libavfilter/vf_bwdif.c | 235 +--- libavfilter/x86/vf_bwdif_init.c | 3 +- libavfilter/yadif.h | 14 ++ libavfilter/yadif_common.c | 12 +- 5 files changed, 64 insertions(+), 234 deletions(-) -- 2.19.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 2/2] avfilter/vf_bwdif: Use common yadif frame management logic
After adding field type management to the common yadif logic, we can remove the duplicate copy of that logic from bwdif. --- libavfilter/bwdif.h | 34 + libavfilter/vf_bwdif.c | 235 +--- libavfilter/x86/vf_bwdif_init.c | 3 +- 3 files changed, 41 insertions(+), 231 deletions(-) diff --git a/libavfilter/bwdif.h b/libavfilter/bwdif.h index 8b42c760a0..889ff772ed 100644 --- a/libavfilter/bwdif.h +++ b/libavfilter/bwdif.h @@ -21,36 +21,10 @@ #include "libavutil/pixdesc.h" #include "avfilter.h" - -enum BWDIFMode { -BWDIF_MODE_SEND_FRAME = 0, ///< send 1 frame for each frame -BWDIF_MODE_SEND_FIELD = 1, ///< send 1 frame for each field -}; - -enum BWDIFParity { -BWDIF_PARITY_TFF = 0, ///< top field first -BWDIF_PARITY_BFF = 1, ///< bottom field first -BWDIF_PARITY_AUTO = -1, ///< auto detection -}; - -enum BWDIFDeint { -BWDIF_DEINT_ALL= 0, ///< deinterlace all frames -BWDIF_DEINT_INTERLACED = 1, ///< only deinterlace frames marked as interlaced -}; +#include "yadif.h" typedef struct BWDIFContext { -const AVClass *class; - -int mode; ///< BWDIFMode -int parity; ///< BWDIFParity -int deint; ///< BWDIFDeint - -int frame_pending; - -AVFrame *cur; -AVFrame *next; -AVFrame *prev; -AVFrame *out; +YADIFContext yadif; void (*filter_intra)(void *dst1, void *cur1, int w, int prefs, int mrefs, int prefs3, int mrefs3, int parity, int clip_max); @@ -61,10 +35,6 @@ typedef struct BWDIFContext { void (*filter_edge)(void *dst, void *prev, void *cur, void *next, int w, int prefs, int mrefs, int prefs2, int mrefs2, int parity, int clip_max, int spat); - -const AVPixFmtDescriptor *csp; -int inter_field; -int eof; } BWDIFContext; void ff_bwdif_init_x86(BWDIFContext *bwdif); diff --git a/libavfilter/vf_bwdif.c b/libavfilter/vf_bwdif.c index b691983611..4ed9cd347d 100644 --- a/libavfilter/vf_bwdif.c +++ b/libavfilter/vf_bwdif.c @@ -216,10 +216,11 @@ static void filter_edge_16bit(void *dst1, void *prev1, void *cur1, void *next1, static int filter_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) { BWDIFContext *s = ctx->priv; +YADIFContext *yadif = &s->yadif; ThreadData *td = arg; -int linesize = s->cur->linesize[td->plane]; -int clip_max = (1 << (s->csp->comp[td->plane].depth)) - 1; -int df = (s->csp->comp[td->plane].depth + 7) / 8; +int linesize = yadif->cur->linesize[td->plane]; +int clip_max = (1 << (yadif->csp->comp[td->plane].depth)) - 1; +int df = (yadif->csp->comp[td->plane].depth + 7) / 8; int refs = linesize / df; int slice_start = (td->h * jobnr ) / nb_jobs; int slice_end = (td->h * (jobnr+1)) / nb_jobs; @@ -227,11 +228,11 @@ static int filter_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) for (y = slice_start; y < slice_end; y++) { if ((y ^ td->parity) & 1) { -uint8_t *prev = &s->prev->data[td->plane][y * linesize]; -uint8_t *cur = &s->cur ->data[td->plane][y * linesize]; -uint8_t *next = &s->next->data[td->plane][y * linesize]; +uint8_t *prev = &yadif->prev->data[td->plane][y * linesize]; +uint8_t *cur = &yadif->cur ->data[td->plane][y * linesize]; +uint8_t *next = &yadif->next->data[td->plane][y * linesize]; uint8_t *dst = &td->frame->data[td->plane][y * td->frame->linesize[td->plane]]; -if (!s->inter_field) { +if (yadif->current_field == YADIF_FIELD_FIRST) { s->filter_intra(dst, cur, td->w, (y + df) < td->h ? refs : -refs, y > (df - 1) ? -refs : refs, (y + 3*df) < td->h ? 3 * refs : -refs, @@ -252,7 +253,7 @@ static int filter_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) } } else { memcpy(&td->frame->data[td->plane][y * td->frame->linesize[td->plane]], - &s->cur->data[td->plane][y * linesize], td->w * df); + &yadif->cur->data[td->plane][y * linesize], td->w * df); } } return 0; @@ -262,16 +263,17 @@ static void filter(AVFilterContext *ctx, AVFrame *dstpic, int parity, int tff) { BWDIFContext *bwdif = ctx->priv; +YADIFContext *yadif = &bwdif->yadif; ThreadData td = { .frame = dstpic, .parity = parity, .tff = tff }; int i; -for (i = 0; i < bwdif->csp->nb_components; i++) { +for (i = 0; i < yadif->csp->nb_components; i++) { int w = dstpic->width; int h = dstpic->height; if (i == 1 || i == 2) { -w = AV_CEIL_RSHIFT(w, bwdif->csp->log2_chroma_w); -h = AV_CEIL_RSHIFT(h, bwdif->csp->log2_chroma_h); +w = AV_CEIL_RSHIFT(w, yadif->csp->log
[FFmpeg-devel] [PATCH 1/2] avfilter/yadif_common: Add field type tracking to help bwdif
The bwdif filter can use common yadif frame management if we track when a field is the first or last field in a sequence. While this information is not used by yadif, the added benefit of removing the duplicated frame management logic makes it worth tracking this state in the common code. --- libavfilter/yadif.h| 14 ++ libavfilter/yadif_common.c | 12 +--- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/libavfilter/yadif.h b/libavfilter/yadif.h index 32d6f4a0d4..02240a4dac 100644 --- a/libavfilter/yadif.h +++ b/libavfilter/yadif.h @@ -41,6 +41,12 @@ enum YADIFDeint { YADIF_DEINT_INTERLACED = 1, ///< only deinterlace frames marked as interlaced }; +enum YADIFCurrentField { +YADIF_FIELD_LAST = -1, ///< The last field in a sequence +YADIF_FIELD_FIRST = 0, ///< The first field in a sequence +YADIF_FIELD_NORMAL = 1, ///< A normal field in the middle of a sequence +}; + typedef struct YADIFContext { const AVClass *class; @@ -70,6 +76,14 @@ typedef struct YADIFContext { int eof; uint8_t *temp_line; int temp_line_size; + +/* + * An algorithm that treats first and/or last fields in a sequence + * differently can use this to detect those cases. It is the algorithm's + * responsibility to set the value to YADIF_FIELD_NORMAL after processing + * the first field. + */ +int current_field; ///< YADIFCurrentField } YADIFContext; void ff_yadif_init_x86(YADIFContext *yadif); diff --git a/libavfilter/yadif_common.c b/libavfilter/yadif_common.c index 19e8ac5281..213eca5396 100644 --- a/libavfilter/yadif_common.c +++ b/libavfilter/yadif_common.c @@ -44,6 +44,8 @@ static int return_frame(AVFilterContext *ctx, int is_second) av_frame_copy_props(yadif->out, yadif->cur); yadif->out->interlaced_frame = 0; +if (yadif->current_field == YADIF_FIELD_LAST) +yadif->current_field = YADIF_FIELD_FIRST; } yadif->filter(ctx, yadif->out, tff ^ !is_second, tff); @@ -103,9 +105,12 @@ int ff_yadif_filter_frame(AVFilterLink *link, AVFrame *frame) yadif->cur = yadif->next; yadif->next = frame; -if (!yadif->cur && -!(yadif->cur = av_frame_clone(yadif->next))) -return AVERROR(ENOMEM); +if (!yadif->cur) { +yadif->cur = av_frame_clone(yadif->next); +if (!yadif->cur) +return AVERROR(ENOMEM); +yadif->current_field = YADIF_FIELD_FIRST; +} if (checkstride(yadif, yadif->next, yadif->cur)) { av_log(ctx, AV_LOG_VERBOSE, "Reallocating frame due to differing stride\n"); @@ -173,6 +178,7 @@ int ff_yadif_request_frame(AVFilterLink *link) if (!next) return AVERROR(ENOMEM); +yadif->current_field = YADIF_FIELD_LAST; next->pts = yadif->next->pts * 2 - yadif->cur->pts; ff_yadif_filter_frame(ctx->inputs[0], next); -- 2.19.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 0/2] Update vf_bwdif to use yadif_common v2
vf_bwdif's frame management logic is almost identical to that of yadif. The only difference is that it tracks the first and last fields in a sequence, and that requires slight changes to the common code. Assuming it's reasonable to do that tracking even though yadif doesn't need it, we can then remove all the duplicated logic. v2: Rename enum values as recommened by Thomas Mundt. Philip Langdale (2): avfilter/yadif_common: Add field type tracking to help bwdif avfilter/vf_bwdif: Use common yadif frame management logic libavfilter/bwdif.h | 34 + libavfilter/vf_bwdif.c | 235 +--- libavfilter/x86/vf_bwdif_init.c | 3 +- libavfilter/yadif.h | 14 ++ libavfilter/yadif_common.c | 12 +- 5 files changed, 64 insertions(+), 234 deletions(-) -- 2.19.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 1/2] avfilter/yadif_common: Add field type tracking to help bwdif
The bwdif filter can use common yadif frame management if we track when a field is the first or last field in a sequence. While this information is not used by yadif, the added benefit of removing the duplicated frame management logic makes it worth tracking this state in the common code. --- libavfilter/yadif.h| 14 ++ libavfilter/yadif_common.c | 12 +--- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/libavfilter/yadif.h b/libavfilter/yadif.h index 32d6f4a0d4..c928911b35 100644 --- a/libavfilter/yadif.h +++ b/libavfilter/yadif.h @@ -41,6 +41,12 @@ enum YADIFDeint { YADIF_DEINT_INTERLACED = 1, ///< only deinterlace frames marked as interlaced }; +enum YADIFCurrentField { +YADIF_FIELD_BACK_END = -1, ///< The last frame in a sequence +YADIF_FIELD_END = 0, ///< The first or last field in a sequence +YADIF_FIELD_NORMAL = 1, ///< A normal field in the middle of a sequence +}; + typedef struct YADIFContext { const AVClass *class; @@ -70,6 +76,14 @@ typedef struct YADIFContext { int eof; uint8_t *temp_line; int temp_line_size; + +/* + * An algorithm that treats first and/or last fields in a sequence + * differently can use this to detect those cases. It is the algorithm's + * responsibility to set the value to YADIF_FIELD_NORMAL after processing + * the first field. + */ +int current_field; ///< YADIFCurrentField } YADIFContext; void ff_yadif_init_x86(YADIFContext *yadif); diff --git a/libavfilter/yadif_common.c b/libavfilter/yadif_common.c index 19e8ac5281..a10cf7a17f 100644 --- a/libavfilter/yadif_common.c +++ b/libavfilter/yadif_common.c @@ -44,6 +44,8 @@ static int return_frame(AVFilterContext *ctx, int is_second) av_frame_copy_props(yadif->out, yadif->cur); yadif->out->interlaced_frame = 0; +if (yadif->current_field == YADIF_FIELD_BACK_END) +yadif->current_field = YADIF_FIELD_END; } yadif->filter(ctx, yadif->out, tff ^ !is_second, tff); @@ -103,9 +105,12 @@ int ff_yadif_filter_frame(AVFilterLink *link, AVFrame *frame) yadif->cur = yadif->next; yadif->next = frame; -if (!yadif->cur && -!(yadif->cur = av_frame_clone(yadif->next))) -return AVERROR(ENOMEM); +if (!yadif->cur) { +yadif->cur = av_frame_clone(yadif->next); +if (!yadif->cur) +return AVERROR(ENOMEM); +yadif->current_field = YADIF_FIELD_END; +} if (checkstride(yadif, yadif->next, yadif->cur)) { av_log(ctx, AV_LOG_VERBOSE, "Reallocating frame due to differing stride\n"); @@ -173,6 +178,7 @@ int ff_yadif_request_frame(AVFilterLink *link) if (!next) return AVERROR(ENOMEM); +yadif->current_field = YADIF_FIELD_BACK_END; next->pts = yadif->next->pts * 2 - yadif->cur->pts; ff_yadif_filter_frame(ctx->inputs[0], next); -- 2.19.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 2/2] avfilter/vf_bwdif: Use common yadif frame management logic
After adding field type management to the common yadif logic, we can remove the duplicate copy of that logic from bwdif. --- libavfilter/bwdif.h | 34 + libavfilter/vf_bwdif.c | 235 +--- libavfilter/x86/vf_bwdif_init.c | 3 +- 3 files changed, 41 insertions(+), 231 deletions(-) diff --git a/libavfilter/bwdif.h b/libavfilter/bwdif.h index 8b42c760a0..889ff772ed 100644 --- a/libavfilter/bwdif.h +++ b/libavfilter/bwdif.h @@ -21,36 +21,10 @@ #include "libavutil/pixdesc.h" #include "avfilter.h" - -enum BWDIFMode { -BWDIF_MODE_SEND_FRAME = 0, ///< send 1 frame for each frame -BWDIF_MODE_SEND_FIELD = 1, ///< send 1 frame for each field -}; - -enum BWDIFParity { -BWDIF_PARITY_TFF = 0, ///< top field first -BWDIF_PARITY_BFF = 1, ///< bottom field first -BWDIF_PARITY_AUTO = -1, ///< auto detection -}; - -enum BWDIFDeint { -BWDIF_DEINT_ALL= 0, ///< deinterlace all frames -BWDIF_DEINT_INTERLACED = 1, ///< only deinterlace frames marked as interlaced -}; +#include "yadif.h" typedef struct BWDIFContext { -const AVClass *class; - -int mode; ///< BWDIFMode -int parity; ///< BWDIFParity -int deint; ///< BWDIFDeint - -int frame_pending; - -AVFrame *cur; -AVFrame *next; -AVFrame *prev; -AVFrame *out; +YADIFContext yadif; void (*filter_intra)(void *dst1, void *cur1, int w, int prefs, int mrefs, int prefs3, int mrefs3, int parity, int clip_max); @@ -61,10 +35,6 @@ typedef struct BWDIFContext { void (*filter_edge)(void *dst, void *prev, void *cur, void *next, int w, int prefs, int mrefs, int prefs2, int mrefs2, int parity, int clip_max, int spat); - -const AVPixFmtDescriptor *csp; -int inter_field; -int eof; } BWDIFContext; void ff_bwdif_init_x86(BWDIFContext *bwdif); diff --git a/libavfilter/vf_bwdif.c b/libavfilter/vf_bwdif.c index b691983611..37165584cf 100644 --- a/libavfilter/vf_bwdif.c +++ b/libavfilter/vf_bwdif.c @@ -216,10 +216,11 @@ static void filter_edge_16bit(void *dst1, void *prev1, void *cur1, void *next1, static int filter_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) { BWDIFContext *s = ctx->priv; +YADIFContext *yadif = &s->yadif; ThreadData *td = arg; -int linesize = s->cur->linesize[td->plane]; -int clip_max = (1 << (s->csp->comp[td->plane].depth)) - 1; -int df = (s->csp->comp[td->plane].depth + 7) / 8; +int linesize = yadif->cur->linesize[td->plane]; +int clip_max = (1 << (yadif->csp->comp[td->plane].depth)) - 1; +int df = (yadif->csp->comp[td->plane].depth + 7) / 8; int refs = linesize / df; int slice_start = (td->h * jobnr ) / nb_jobs; int slice_end = (td->h * (jobnr+1)) / nb_jobs; @@ -227,11 +228,11 @@ static int filter_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) for (y = slice_start; y < slice_end; y++) { if ((y ^ td->parity) & 1) { -uint8_t *prev = &s->prev->data[td->plane][y * linesize]; -uint8_t *cur = &s->cur ->data[td->plane][y * linesize]; -uint8_t *next = &s->next->data[td->plane][y * linesize]; +uint8_t *prev = &yadif->prev->data[td->plane][y * linesize]; +uint8_t *cur = &yadif->cur ->data[td->plane][y * linesize]; +uint8_t *next = &yadif->next->data[td->plane][y * linesize]; uint8_t *dst = &td->frame->data[td->plane][y * td->frame->linesize[td->plane]]; -if (!s->inter_field) { +if (yadif->current_field == YADIF_FIELD_END) { s->filter_intra(dst, cur, td->w, (y + df) < td->h ? refs : -refs, y > (df - 1) ? -refs : refs, (y + 3*df) < td->h ? 3 * refs : -refs, @@ -252,7 +253,7 @@ static int filter_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) } } else { memcpy(&td->frame->data[td->plane][y * td->frame->linesize[td->plane]], - &s->cur->data[td->plane][y * linesize], td->w * df); + &yadif->cur->data[td->plane][y * linesize], td->w * df); } } return 0; @@ -262,16 +263,17 @@ static void filter(AVFilterContext *ctx, AVFrame *dstpic, int parity, int tff) { BWDIFContext *bwdif = ctx->priv; +YADIFContext *yadif = &bwdif->yadif; ThreadData td = { .frame = dstpic, .parity = parity, .tff = tff }; int i; -for (i = 0; i < bwdif->csp->nb_components; i++) { +for (i = 0; i < yadif->csp->nb_components; i++) { int w = dstpic->width; int h = dstpic->height; if (i == 1 || i == 2) { -w = AV_CEIL_RSHIFT(w, bwdif->csp->log2_chroma_w); -h = AV_CEIL_RSHIFT(h, bwdif->csp->log2_chroma_h); +w = AV_CEIL_RSHIFT(w, yadif->csp->log2_
Re: [FFmpeg-devel] [PATCH 0/2] Update vf_bwdif to use yadif_common v2
On Tue, 13 Nov 2018 02:11:15 +0100 Thomas Mundt wrote: > Am So., 11. Nov. 2018 um 20:47 Uhr schrieb Philip Langdale < > phil...@overt.org>: > > > vf_bwdif's frame management logic is almost identical to that of > > yadif. The only difference is that it tracks the first and last > > fields in a sequence, and that requires slight changes to the > > common code. > > > > Assuming it's reasonable to do that tracking even though yadif > > doesn't need it, we can then remove all the duplicated logic. > > > > v2: Rename enum values as recommened by Thomas Mundt. > > > > Philip Langdale (2): > > avfilter/yadif_common: Add field type tracking to help bwdif > > avfilter/vf_bwdif: Use common yadif frame management logic > > > > libavfilter/bwdif.h | 34 + > > libavfilter/vf_bwdif.c | 235 > > +--- libavfilter/x86/vf_bwdif_init.c > > | 3 +- libavfilter/yadif.h | 14 ++ > > libavfilter/yadif_common.c | 12 +- > > 5 files changed, 64 insertions(+), 234 deletions(-) > > > > Patch lgtm. Thanks. Pushed. --phil ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] HEVC decoder for Raspberry Pi
On 2018-11-15 05:48, John Cox wrote: Now one way it could be integrated would be as a seperate decoder That is how I've currently built it and therefore probably the easiest option. another is inside the hevc decoder It started life there but became a very uneasy fit with too many ifdefs. a 3rd is, similar to the hwaccel stuff and a 4th would be that the decoder could be an external lib that is used through hwaccel similar to other hwaccel libs Possibly - this is where I wanted advice as my attempts to understand how that lot is meant to work simply ended in confusion or a feeling that what I wanted to do was a very bad fit with the current framework - some of the issue with that is in vps/sps/pps setup where I build somewhat different tables to the common code that is used by most other h/w decodes. you need to obtain the communities preferrance here not just my oppinion ... especially comments from people activly working on hwaccel stuff are needed here I welcome their comments Hi John, I'm not exactly an hwaccel expert (Hopefully jkqxz will chime in), but your scenario looks like one that fits naturally into the hwaccel model on the surface. You don't want to duplicate the whole decoder and you want to accelerate specific steps using an offload mechanism and there's a custom pix fmt involved. It's not a traditional GPU offload but it's a close enough analogue that it's where I'd start. So, I think you are basically doing two things: 1) Defining a new hwcontext that encapsulates your offload co-processor and an accompanying hw pix fmt for the sand format in GPU memory. The hwcontext API gives you hooks to define transfers to/from system memory. This replaces the filters you have in your current implementation. 2) You then define an an hwaccel that uses the new hwcontext and format. You mentioned you needed to organise the hevc metadata differently from how ffmpeg does, but this is true for all hwaccels - if you look at the existing ones, there's lots of boilerplate code doing various transformations and organisations on this; that's just life. It's tedious but you only do it once. You then need to write your actual decode. Unlike a full hwaccel, it sounds like parts of the process are still CPU code, and maybe could be the same code in the regular software decoding path. You might be able to refactor to use it, or have to duplicate it, but that's not the end of the world. Hopefully, that's of some use to you. --phil ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] fate-source : add cuda_check to ignore files list
On Sat, 17 Nov 2018 17:05:00 +0100 Martin Vignali wrote: > Hello, > > Patch in attach fix make fate-source error for cuda_check files > > Martin Thanks for pointing this out. I've pushed a slightly different fix where I made the inclusion guards follow the standard pattern. --phil ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] movtext decode/encode improvements
On Mon, 6 Apr 2020 11:51:55 -0600 John Stebbins wrote: > Patch series adds more complete decoding and encoding of color, alpha, > font size, font name, and style tags for movtext. It also fixes a > number of bugs. > Hi John, Thanks for doing all of this! I'll try and take a look at these over the next few days. --phil ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH 01/23] lavc/movtextdec: fix ass header colors
On Mon, 6 Apr 2020 11:51:56 -0600 John Stebbins wrote: > A conversion from rgb to bgr is necessary > --- > libavcodec/movtextdec.c | 11 +++ > 1 file changed, 7 insertions(+), 4 deletions(-) > > diff --git a/libavcodec/movtextdec.c b/libavcodec/movtextdec.c > index c38c5edce6..05becaf64d 100644 > --- a/libavcodec/movtextdec.c > +++ b/libavcodec/movtextdec.c > @@ -48,6 +48,8 @@ > #define TOP_CENTER 8 > #define TOP_RIGHT 9 > > +#define RGB_TO_BGR(c) (((c) & 0xff) << 16 | ((c) & 0xff00) | (((c) > >> 16) & 0xff)) + > typedef struct { > char *font; > int fontsize; > @@ -448,10 +450,11 @@ static int mov_text_init(AVCodecContext *avctx) > { MovTextContext *m = avctx->priv_data; > ret = mov_text_tx3g(avctx, m); > if (ret == 0) { > -return ff_ass_subtitle_header(avctx, m->d.font, > m->d.fontsize, m->d.color, > -m->d.back_color, m->d.bold, > m->d.italic, > -m->d.underline, > ASS_DEFAULT_BORDERSTYLE, > -m->d.alignment); > +return ff_ass_subtitle_header(avctx, m->d.font, > m->d.fontsize, > +RGB_TO_BGR(m->d.color), > +RGB_TO_BGR(m->d.back_color), > +m->d.bold, m->d.italic, m->d.underline, > +ASS_DEFAULT_BORDERSTYLE, m->d.alignment); > } else > return ff_ass_subtitle_header_default(avctx); > } LGTM. --phil ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH 02/23] lavc/movtextdec: simplify style record walk
On Mon, 6 Apr 2020 11:51:57 -0600 John Stebbins wrote: > It's not necessary to walk the style record list twice per subtitle > character. style records are in order and do not overlap. > --- > libavcodec/movtextdec.c | 38 -- > 1 file changed, 20 insertions(+), 18 deletions(-) > > diff --git a/libavcodec/movtextdec.c b/libavcodec/movtextdec.c > index 05becaf64d..47a8401119 100644 > --- a/libavcodec/movtextdec.c > +++ b/libavcodec/movtextdec.c > @@ -355,8 +355,9 @@ static int text_to_ass(AVBPrint *buf, const char > *text, const char *text_end, { > MovTextContext *m = avctx->priv_data; > int i = 0; > -int j = 0; > int text_pos = 0; > +int style_active = 0; > +int entry = 0; > > if (text < text_end && m->box_flags & TWRP_BOX) { > if (m->w.wrap_flag == 1) { > @@ -369,26 +370,27 @@ static int text_to_ass(AVBPrint *buf, const > char *text, const char *text_end, while (text < text_end) { > int len; > > -if (m->box_flags & STYL_BOX) { > -for (i = 0; i < m->style_entries; i++) { > -if (m->s[i]->style_flag && text_pos == > m->s[i]->style_end) { > -av_bprintf(buf, "{\\r}"); > +if ((m->box_flags & STYL_BOX) && entry < m->style_entries) { > +if (text_pos == m->s[entry]->style_start) { > +style_active = 1; > +if (m->s[entry]->style_flag & STYLE_FLAG_BOLD) > +av_bprintf(buf, "{\\b1}"); > +if (m->s[entry]->style_flag & STYLE_FLAG_ITALIC) > +av_bprintf(buf, "{\\i1}"); > +if (m->s[entry]->style_flag & STYLE_FLAG_UNDERLINE) > +av_bprintf(buf, "{\\u1}"); > +av_bprintf(buf, "{\\fs%d}", m->s[entry]->fontsize); > +for (i = 0; i < m->ftab_entries; i++) { > +if (m->s[entry]->style_fontID == > m->ftab[i]->fontID) > +av_bprintf(buf, "{\\fn%s}", > m->ftab[i]->font); } > } > -for (i = 0; i < m->style_entries; i++) { > -if (m->s[i]->style_flag && text_pos == > m->s[i]->style_start) { > -if (m->s[i]->style_flag & STYLE_FLAG_BOLD) > -av_bprintf(buf, "{\\b1}"); > -if (m->s[i]->style_flag & STYLE_FLAG_ITALIC) > -av_bprintf(buf, "{\\i1}"); > -if (m->s[i]->style_flag & STYLE_FLAG_UNDERLINE) > -av_bprintf(buf, "{\\u1}"); > -av_bprintf(buf, "{\\fs%d}", m->s[i]->fontsize); > -for (j = 0; j < m->ftab_entries; j++) { > -if (m->s[i]->style_fontID == > m->ftab[j]->fontID) > -av_bprintf(buf, "{\\fn%s}", > m->ftab[j]->font); > -} > +if (text_pos == m->s[entry]->style_end) { > +if (style_active) { > +av_bprintf(buf, "{\\r}"); > +style_active = 0; > } > +entry++; > } > } > if (m->box_flags & HLIT_BOX) { OK. I could not convince myself originally that styles could not overlap, but I could easily have missed that in the spec. --phil ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH 03/23] lavc/movtextdec: fix bold, italic, underline flags
On Mon, 6 Apr 2020 11:51:58 -0600 John Stebbins wrote: > They should be 0 or 1 so that 0 or -1 is written to the ass header > --- > libavcodec/movtextdec.c | 6 +++--- > 1 file changed, 3 insertions(+), 3 deletions(-) > > diff --git a/libavcodec/movtextdec.c b/libavcodec/movtextdec.c > index 47a8401119..d6896562c2 100644 > --- a/libavcodec/movtextdec.c > +++ b/libavcodec/movtextdec.c > @@ -193,9 +193,9 @@ static int mov_text_tx3g(AVCodecContext *avctx, > MovTextContext *m) tx3g_ptr += 2; > // face-style-flags > s_default.style_flag = *tx3g_ptr++; > -m->d.bold = s_default.style_flag & STYLE_FLAG_BOLD; > -m->d.italic = s_default.style_flag & STYLE_FLAG_ITALIC; > -m->d.underline = s_default.style_flag & STYLE_FLAG_UNDERLINE; > +m->d.bold = !!(s_default.style_flag & STYLE_FLAG_BOLD); > +m->d.italic = !!(s_default.style_flag & STYLE_FLAG_ITALIC); > +m->d.underline = !!(s_default.style_flag & STYLE_FLAG_UNDERLINE); > // fontsize > m->d.fontsize = *tx3g_ptr++; > // Primary color LGTM. --phil ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH 04/23] lavc/movtextdec: handle changes to default style flags
On Mon, 6 Apr 2020 11:51:59 -0600 John Stebbins wrote: > Style flags were only being turned on. If the default was on and > style record turned off, style flag remained on. > --- > libavcodec/movtextdec.c | 24 +++- > 1 file changed, 15 insertions(+), 9 deletions(-) > > diff --git a/libavcodec/movtextdec.c b/libavcodec/movtextdec.c > index d6896562c2..a3e37d013d 100644 > --- a/libavcodec/movtextdec.c > +++ b/libavcodec/movtextdec.c > @@ -55,9 +55,9 @@ typedef struct { > int fontsize; > int color; > int back_color; > -int bold; > -int italic; > -int underline; > +uint8_t bold; > +uint8_t italic; > +uint8_t underline; > int alignment; > } MovTextDefault; > > @@ -70,6 +70,9 @@ typedef struct { > uint16_t style_start; > uint16_t style_end; > uint8_t style_flag; > +uint8_t bold; > +uint8_t italic; > +uint8_t underline; > uint8_t fontsize; > uint16_t style_fontID; > } StyleBox; > @@ -313,6 +316,9 @@ static int decode_styl(const uint8_t *tsmb, > MovTextContext *m, AVPacket *avpkt) m->s_temp->style_fontID = > AV_RB16(tsmb); tsmb += 2; > m->s_temp->style_flag = AV_RB8(tsmb); > +m->s_temp->bold = !!(m->s_temp->style_flag & > STYLE_FLAG_BOLD); > +m->s_temp->italic = !!(m->s_temp->style_flag & > STYLE_FLAG_ITALIC); > +m->s_temp->underline = !!(m->s_temp->style_flag & > STYLE_FLAG_UNDERLINE); tsmb++; > m->s_temp->fontsize = AV_RB8(tsmb); > av_dynarray_add(&m->s, &m->count_s, m->s_temp); > @@ -373,12 +379,12 @@ static int text_to_ass(AVBPrint *buf, const > char *text, const char *text_end, if ((m->box_flags & STYL_BOX) && > entry < m->style_entries) { if (text_pos == m->s[entry]->style_start) > { style_active = 1; > -if (m->s[entry]->style_flag & STYLE_FLAG_BOLD) > -av_bprintf(buf, "{\\b1}"); > -if (m->s[entry]->style_flag & STYLE_FLAG_ITALIC) > -av_bprintf(buf, "{\\i1}"); > -if (m->s[entry]->style_flag & STYLE_FLAG_UNDERLINE) > -av_bprintf(buf, "{\\u1}"); > +if (m->s[entry]->bold ^ m->d.bold) > +av_bprintf(buf, "{\\b%d}", m->s[entry]->bold); > +if (m->s[entry]->italic ^ m->d.italic) > +av_bprintf(buf, "{\\i%d}", m->s[entry]->italic); > +if (m->s[entry]->underline ^ m->d.underline) > +av_bprintf(buf, "{\\u%d}", > m->s[entry]->underline); av_bprintf(buf, "{\\fs%d}", > m->s[entry]->fontsize); for (i = 0; i < m->ftab_entries; i++) { > if (m->s[entry]->style_fontID == > m->ftab[i]->fontID) LGTM. --phil ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH 05/23] lavc/movtextdec: only write fontsize, fontID tags if not default
On Mon, 6 Apr 2020 11:52:00 -0600 John Stebbins wrote: > --- > libavcodec/movtextdec.c | 20 +++- > 1 file changed, 11 insertions(+), 9 deletions(-) > > diff --git a/libavcodec/movtextdec.c b/libavcodec/movtextdec.c > index a3e37d013d..6c7d93702e 100644 > --- a/libavcodec/movtextdec.c > +++ b/libavcodec/movtextdec.c > @@ -51,8 +51,9 @@ > #define RGB_TO_BGR(c) (((c) & 0xff) << 16 | ((c) & 0xff00) | (((c) > >> 16) & 0xff)) > typedef struct { > +uint16_t fontID; > char *font; > -int fontsize; > +uint8_t fontsize; > int color; > int back_color; > uint8_t bold; > @@ -146,7 +147,6 @@ static int mov_text_tx3g(AVCodecContext *avctx, > MovTextContext *m) uint8_t *tx3g_ptr = avctx->extradata; > int i, box_size, font_length; > int8_t v_align, h_align; > -int style_fontID; > StyleBox s_default; > > m->count_f = 0; > @@ -192,7 +192,7 @@ static int mov_text_tx3g(AVCodecContext *avctx, > MovTextContext *m) // StyleRecord > tx3g_ptr += 4; > // fontID > -style_fontID = AV_RB16(tx3g_ptr); > +m->d.fontID = AV_RB16(tx3g_ptr); > tx3g_ptr += 2; > // face-style-flags > s_default.style_flag = *tx3g_ptr++; > @@ -252,7 +252,7 @@ static int mov_text_tx3g(AVCodecContext *avctx, > MovTextContext *m) tx3g_ptr = tx3g_ptr + font_length; > } > for (i = 0; i < m->ftab_entries; i++) { > -if (style_fontID == m->ftab[i]->fontID) > +if (m->d.fontID == m->ftab[i]->fontID) > m->d.font = m->ftab[i]->font; > } > return 0; > @@ -385,11 +385,13 @@ static int text_to_ass(AVBPrint *buf, const > char *text, const char *text_end, av_bprintf(buf, "{\\i%d}", > m->s[entry]->italic); if (m->s[entry]->underline ^ m->d.underline) > av_bprintf(buf, "{\\u%d}", > m->s[entry]->underline); > -av_bprintf(buf, "{\\fs%d}", m->s[entry]->fontsize); > -for (i = 0; i < m->ftab_entries; i++) { > -if (m->s[entry]->style_fontID == > m->ftab[i]->fontID) > -av_bprintf(buf, "{\\fn%s}", > m->ftab[i]->font); > -} > +if (m->s[entry]->fontsize != m->d.fontsize) > +av_bprintf(buf, "{\\fs%d}", > m->s[entry]->fontsize); > +if (m->s[entry]->style_fontID != m->d.fontID) > +for (i = 0; i < m->ftab_entries; i++) { > +if (m->s[entry]->style_fontID == > m->ftab[i]->fontID) > +av_bprintf(buf, "{\\fn%s}", > m->ftab[i]->font); > +} > } > if (text_pos == m->s[entry]->style_end) { > if (style_active) { LGTM. --phil ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH 02/23] lavc/movtextdec: simplify style record walk
On Mon, 6 Apr 2020 22:09:22 + John Stebbins wrote: > > I went back and double checked this in the spec before changing the > code. > > "The styles shall be ordered by starting character offset, and the > starting offset of one style record shall be greater than or equal to > the ending character offset of the preceding record; styles records > shall not overlap their character ranges." Alright. Great! LGTM then. --phil ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH 06/23] lavc/movtextdec: make sure default font name is set
On Mon, 6 Apr 2020 11:52:01 -0600 John Stebbins wrote: > --- > libavcodec/movtextdec.c | 4 +++- > 1 file changed, 3 insertions(+), 1 deletion(-) > > diff --git a/libavcodec/movtextdec.c b/libavcodec/movtextdec.c > index 6c7d93702e..2481c71af6 100644 > --- a/libavcodec/movtextdec.c > +++ b/libavcodec/movtextdec.c > @@ -52,7 +52,7 @@ > > typedef struct { > uint16_t fontID; > -char *font; > +const char *font; > uint8_t fontsize; > int color; > int back_color; > @@ -251,6 +251,8 @@ static int mov_text_tx3g(AVCodecContext *avctx, > MovTextContext *m) m->ftab_temp = NULL; > tx3g_ptr = tx3g_ptr + font_length; > } > +// In case of broken header, init default font > +m->d.font = ASS_DEFAULT_FONT; > for (i = 0; i < m->ftab_entries; i++) { > if (m->d.fontID == m->ftab[i]->fontID) > m->d.font = m->ftab[i]->font; LGTM. --phil ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH 07/23] lavc/movtextdec: add alpha default to ass header colors
On Mon, 6 Apr 2020 11:52:02 -0600 John Stebbins wrote: > --- > libavcodec/movtextdec.c| 14 ++ > tests/ref/fate/sub-movtext | 2 +- > 2 files changed, 11 insertions(+), 5 deletions(-) > > diff --git a/libavcodec/movtextdec.c b/libavcodec/movtextdec.c > index 2481c71af6..eb9c7f5755 100644 > --- a/libavcodec/movtextdec.c > +++ b/libavcodec/movtextdec.c > @@ -55,7 +55,9 @@ typedef struct { > const char *font; > uint8_t fontsize; > int color; > +uint8_t alpha; > int back_color; > +uint8_t back_alpha; > uint8_t bold; > uint8_t italic; > uint8_t underline; > @@ -186,7 +188,9 @@ static int mov_text_tx3g(AVCodecContext *avctx, > MovTextContext *m) } > // Background Color > m->d.back_color = AV_RB24(tx3g_ptr); > -tx3g_ptr += 4; > +tx3g_ptr += 3; > +m->d.back_alpha = AV_RB8(tx3g_ptr); > +tx3g_ptr += 1; > // BoxRecord > tx3g_ptr += 8; > // StyleRecord > @@ -203,7 +207,9 @@ static int mov_text_tx3g(AVCodecContext *avctx, > MovTextContext *m) m->d.fontsize = *tx3g_ptr++; > // Primary color > m->d.color = AV_RB24(tx3g_ptr); > -tx3g_ptr += 4; > +tx3g_ptr += 3; > +m->d.alpha = AV_RB8(tx3g_ptr); > +tx3g_ptr += 1; > // FontRecord > // FontRecord Size > tx3g_ptr += 4; > @@ -463,8 +469,8 @@ static int mov_text_init(AVCodecContext *avctx) { > ret = mov_text_tx3g(avctx, m); > if (ret == 0) { > return ff_ass_subtitle_header(avctx, m->d.font, > m->d.fontsize, > -RGB_TO_BGR(m->d.color), > -RGB_TO_BGR(m->d.back_color), > +(255 - m->d.alpha) << 24 | > RGB_TO_BGR(m->d.color), > +(255 - m->d.back_alpha) << 24 | > RGB_TO_BGR(m->d.back_color), m->d.bold, m->d.italic, m->d.underline, > ASS_DEFAULT_BORDERSTYLE, m->d.alignment); > } else > diff --git a/tests/ref/fate/sub-movtext b/tests/ref/fate/sub-movtext > index 94ed22d318..6047060918 100644 > --- a/tests/ref/fate/sub-movtext > +++ b/tests/ref/fate/sub-movtext > @@ -6,7 +6,7 @@ PlayResY: 288 > > [V4+ Styles] > Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, > OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, > ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, > Alignment, MarginL, MarginR, MarginV, Encoding -Style: > Default,Serif,18,&Hff,&Hff,&H0,&H0,0,0,0,0,100,100,0,0,1,1,0,2,10,10,10,0 > +Style: > Default,Serif,18,&Hff,&Hff,&Hff00,&Hff00,0,0,0,0,100,100,0,0,1,1,0,2,10,10,10,0 > [Events] Format: Layer, Start, End, Style, Name, MarginL, MarginR, > MarginV, Effect, Text LGTM. --phil ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH 08/23] lavc/movtextdec: add color and alpha style tags
On Mon, 6 Apr 2020 11:52:03 -0600 John Stebbins wrote: > --- > libavcodec/movtextdec.c | 15 --- > 1 file changed, 12 insertions(+), 3 deletions(-) > > diff --git a/libavcodec/movtextdec.c b/libavcodec/movtextdec.c > index eb9c7f5755..4d5dcdf5e7 100644 > --- a/libavcodec/movtextdec.c > +++ b/libavcodec/movtextdec.c > @@ -76,6 +76,8 @@ typedef struct { > uint8_t bold; > uint8_t italic; > uint8_t underline; > +int color; > +uint8_t alpha; > uint8_t fontsize; > uint16_t style_fontID; > } StyleBox; > @@ -329,14 +331,16 @@ static int decode_styl(const uint8_t *tsmb, > MovTextContext *m, AVPacket *avpkt) m->s_temp->underline = > !!(m->s_temp->style_flag & STYLE_FLAG_UNDERLINE); tsmb++; > m->s_temp->fontsize = AV_RB8(tsmb); > +tsmb++; > +m->s_temp->color = AV_RB24(tsmb); > +tsmb += 3; > +m->s_temp->alpha = AV_RB8(tsmb); > +tsmb++; > av_dynarray_add(&m->s, &m->count_s, m->s_temp); > if(!m->s) { > mov_text_cleanup(m); > return AVERROR(ENOMEM); > } > -tsmb++; > -// text-color-rgba > -tsmb += 4; > } > return 0; > } > @@ -400,6 +404,11 @@ static int text_to_ass(AVBPrint *buf, const char > *text, const char *text_end, if (m->s[entry]->style_fontID == > m->ftab[i]->fontID) av_bprintf(buf, "{\\fn%s}", m->ftab[i]->font); > } > +if (m->d.color != m->s[entry]->color) > +av_bprintf(buf, "{\\1c&H%X&}", > + RGB_TO_BGR(m->s[entry]->color)); > +if (m->d.alpha != m->s[entry]->alpha) > +av_bprintf(buf, "{\\1a&H%02X&}", 255 - > m->s[entry]->alpha); } > if (text_pos == m->s[entry]->style_end) { > if (style_active) { LGTM. --phil ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH 09/23] lavc/movtextdec: restore active style color after hilite
On Mon, 6 Apr 2020 11:52:04 -0600 John Stebbins wrote: > --- > libavcodec/movtextdec.c | 14 +- > 1 file changed, 9 insertions(+), 5 deletions(-) > > diff --git a/libavcodec/movtextdec.c b/libavcodec/movtextdec.c > index 4d5dcdf5e7..f3a504b47b 100644 > --- a/libavcodec/movtextdec.c > +++ b/libavcodec/movtextdec.c > @@ -376,6 +376,7 @@ static int text_to_ass(AVBPrint *buf, const char > *text, const char *text_end, int text_pos = 0; > int style_active = 0; > int entry = 0; > +int color = m->d.color; > > if (text < text_end && m->box_flags & TWRP_BOX) { > if (m->w.wrap_flag == 1) { > @@ -404,9 +405,10 @@ static int text_to_ass(AVBPrint *buf, const char > *text, const char *text_end, if (m->s[entry]->style_fontID == > m->ftab[i]->fontID) av_bprintf(buf, "{\\fn%s}", m->ftab[i]->font); > } > -if (m->d.color != m->s[entry]->color) > -av_bprintf(buf, "{\\1c&H%X&}", > - RGB_TO_BGR(m->s[entry]->color)); > +if (m->d.color != m->s[entry]->color) { > +color = m->s[entry]->color; > +av_bprintf(buf, "{\\1c&H%X&}", > RGB_TO_BGR(color)); > +} > if (m->d.alpha != m->s[entry]->alpha) > av_bprintf(buf, "{\\1a&H%02X&}", 255 - > m->s[entry]->alpha); } > @@ -414,6 +416,7 @@ static int text_to_ass(AVBPrint *buf, const char > *text, const char *text_end, if (style_active) { > av_bprintf(buf, "{\\r}"); > style_active = 0; > +color = m->d.color; > } > entry++; > } > @@ -435,9 +438,10 @@ static int text_to_ass(AVBPrint *buf, const char > *text, const char *text_end, } > if (text_pos == m->h.hlit_end) { > if (m->box_flags & HCLR_BOX) { > -av_bprintf(buf, "{\\2c&H00&}"); > +av_bprintf(buf, "{\\2c&H%X&}", > RGB_TO_BGR(m->d.color)); } else { > -av_bprintf(buf, > "{\\1c&HFF&}{\\2c&H00&}"); > +av_bprintf(buf, "{\\1c&H%X&}{\\2c&H%X&}", > + RGB_TO_BGR(color), > RGB_TO_BGR(m->d.color)); } > } > } LGTM. --phil ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH 12/23] lavc/movtextenc: use correct color component order
On Mon, 6 Apr 2020 11:52:07 -0600 John Stebbins wrote: > --- > libavcodec/movtextenc.c | 10 +++--- > 1 file changed, 7 insertions(+), 3 deletions(-) > > diff --git a/libavcodec/movtextenc.c b/libavcodec/movtextenc.c > index c19ef384bc..8638e303fe 100644 > --- a/libavcodec/movtextenc.c > +++ b/libavcodec/movtextenc.c > @@ -39,6 +39,7 @@ > #define HLIT_BOX (1<<1) > #define HCLR_BOX (1<<2) > > +#define BGR_TO_RGB(c) (((c) & 0xff) << 16 | ((c) & 0xff00) | (((c) > >> 16) & 0xff)) #define av_bprint_append_any(buf, data, size) > >> av_bprint_append_data(buf, ((const char*)data), size) > > typedef struct { > @@ -134,13 +135,14 @@ static void encode_hlit(MovTextContext *s, > uint32_t tsmb_type) > static void encode_hclr(MovTextContext *s, uint32_t tsmb_type) > { > -uint32_t tsmb_size; > +uint32_t tsmb_size, color; > if (s->box_flags & HCLR_BOX) { > tsmb_size = 12; > tsmb_size = AV_RB32(&tsmb_size); > +color = AV_RB32(&s->hclr.color); > av_bprint_append_any(&s->buffer, &tsmb_size, 4); > av_bprint_append_any(&s->buffer, &tsmb_type, 4); > -av_bprint_append_any(&s->buffer, &s->hclr.color, 4); > +av_bprint_append_any(&s->buffer, &color, 4); > } > } > > @@ -289,6 +291,8 @@ static void mov_text_style_cb(void *priv, const > char style, int close) static void mov_text_color_cb(void *priv, > unsigned int color, unsigned int color_id) { > MovTextContext *s = priv; > + > +color = BGR_TO_RGB(color) << 8; > if (color_id == 2) {//secondary color changes > if (s->box_flags & HLIT_BOX) { //close tag > s->hlit.end = AV_RB16(&s->text_pos); > @@ -296,7 +300,7 @@ static void mov_text_color_cb(void *priv, > unsigned int color, unsigned int color s->box_flags |= HCLR_BOX; > s->box_flags |= HLIT_BOX; > s->hlit.start = AV_RB16(&s->text_pos); > -s->hclr.color = color | (0xFF << 24); //set alpha value > to FF > +s->hclr.color = color | 0xFF; //set alpha value to FF > } > } > /* If there are more than one secondary color changes in ASS, > take start of LGTM --phil ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH 13/23] lavc/movtextenc: keep values in native byte order till written
On Mon, 6 Apr 2020 11:52:08 -0600 John Stebbins wrote: > --- > libavcodec/movtextenc.c | 38 ++ > 1 file changed, 22 insertions(+), 16 deletions(-) > > diff --git a/libavcodec/movtextenc.c b/libavcodec/movtextenc.c > index 8638e303fe..5e5b786f44 100644 > --- a/libavcodec/movtextenc.c > +++ b/libavcodec/movtextenc.c > @@ -68,7 +68,6 @@ typedef struct { > HilightcolorBox hclr; > int count; > uint8_t box_flags; > -uint16_t style_entries; > uint16_t style_fontID; > uint8_t style_fontsize; > uint32_t style_color; > @@ -96,10 +95,11 @@ static void encode_styl(MovTextContext *s, > uint32_t tsmb_type) { > int j; > uint32_t tsmb_size; > +uint16_t style_entries; > if (s->box_flags & STYL_BOX) { > tsmb_size = s->count * STYLE_RECORD_SIZE + SIZE_ADD; > tsmb_size = AV_RB32(&tsmb_size); > -s->style_entries = AV_RB16(&s->count); > +style_entries = AV_RB16(&s->count); > s->style_fontID = 0x00 | 0x01<<8; > s->style_fontsize = 0x12; > s->style_color = MKTAG(0xFF, 0xFF, 0xFF, 0xFF); > @@ -107,10 +107,14 @@ static void encode_styl(MovTextContext *s, > uint32_t tsmb_type) but will come from ASS style in the future*/ > av_bprint_append_any(&s->buffer, &tsmb_size, 4); > av_bprint_append_any(&s->buffer, &tsmb_type, 4); > -av_bprint_append_any(&s->buffer, &s->style_entries, 2); > +av_bprint_append_any(&s->buffer, &style_entries, 2); > for (j = 0; j < s->count; j++) { > -av_bprint_append_any(&s->buffer, > &s->style_attributes[j]->style_start, 2); > -av_bprint_append_any(&s->buffer, > &s->style_attributes[j]->style_end, 2); > +uint16_t style_start, style_end; > + > +style_start = > AV_RB16(&s->style_attributes[j]->style_start); > +style_end= > AV_RB16(&s->style_attributes[j]->style_end); > +av_bprint_append_any(&s->buffer, &style_start, 2); > +av_bprint_append_any(&s->buffer, &style_end, 2); > av_bprint_append_any(&s->buffer, &s->style_fontID, 2); > av_bprint_append_any(&s->buffer, > &s->style_attributes[j]->style_flag, 1); > av_bprint_append_any(&s->buffer, &s->style_fontsize, 1); @@ -123,13 > +127,16 @@ static void encode_styl(MovTextContext *s, uint32_t > tsmb_type) static void encode_hlit(MovTextContext *s, uint32_t > tsmb_type) { uint32_t tsmb_size; > +uint16_t start, end; > if (s->box_flags & HLIT_BOX) { > tsmb_size = 12; > tsmb_size = AV_RB32(&tsmb_size); > +start = AV_RB16(&s->hlit.start); > +end = AV_RB16(&s->hlit.end); > av_bprint_append_any(&s->buffer, &tsmb_size, 4); > av_bprint_append_any(&s->buffer, &tsmb_type, 4); > -av_bprint_append_any(&s->buffer, &s->hlit.start, 2); > -av_bprint_append_any(&s->buffer, &s->hlit.end, 2); > +av_bprint_append_any(&s->buffer, &start, 2); > +av_bprint_append_any(&s->buffer, &end, 2); > } > } > > @@ -222,10 +229,10 @@ static void mov_text_style_cb(void *priv, const > char style, int close) } > > s->style_attributes_temp->style_flag = 0; > -s->style_attributes_temp->style_start = > AV_RB16(&s->text_pos); > +s->style_attributes_temp->style_start = s->text_pos; > } else { > if (s->style_attributes_temp->style_flag) { //break the > style record here and start a new one > -s->style_attributes_temp->style_end = > AV_RB16(&s->text_pos); > +s->style_attributes_temp->style_end = s->text_pos; > av_dynarray_add(&s->style_attributes, &s->count, > s->style_attributes_temp); s->style_attributes_temp = > av_malloc(sizeof(*s->style_attributes_temp)); if > (!s->style_attributes_temp) { @@ -236,10 +243,10 @@ static void > mov_text_style_cb(void *priv, const char style, int close) } > > s->style_attributes_temp->style_flag = > s->style_attributes[s->count - 1]->style_flag; > -s->style_attributes_temp->style_start = > AV_RB16(&s->text_pos); > +s->style_attributes_temp->style_start = s->text_pos; > } else { > s->style_attributes_temp->style_flag = 0; > -s->style_attributes_temp->style_start = > AV_RB16(&s->text_pos); > +s->style_attributes_temp->style_start = s->text_pos; > } > } > switch (style){ > @@ -257,7 +264,7 @@ static void mov_text_style_cb(void *priv, const > char style, int close) av_log(s->avctx, AV_LOG_WARNING, "Ignoring > unmatched close tag\n"); return; > } else { > -s->style_attributes_temp->style_end = AV_RB16(&s->text_pos); > +s->style_attributes_temp->style_end = s->text_pos; > av_dynarray_add(&s->style_attributes, &s->count, > s->style_attributes_temp); > s->style_attributes_temp = > av_
Re: [FFmpeg-devel] [PATCH 14/23] lavc/movtextenc: simplify style record updates
On Mon, 6 Apr 2020 11:52:09 -0600 John Stebbins wrote: > Makes style update code easier to extend for style types not yet > handled --- > libavcodec/movtextenc.c | 131 > +++- 1 file changed, 62 > insertions(+), 69 deletions(-) > > diff --git a/libavcodec/movtextenc.c b/libavcodec/movtextenc.c > index 5e5b786f44..05532cd544 100644 > --- a/libavcodec/movtextenc.c > +++ b/libavcodec/movtextenc.c > @@ -89,6 +89,10 @@ static void mov_text_cleanup(MovTextContext *s) > } > av_freep(&s->style_attributes); > } > +if (s->style_attributes_temp) { > +s->style_attributes_temp->style_flag = 0; > +s->style_attributes_temp->style_start = 0; > +} > } > > static void encode_styl(MovTextContext *s, uint32_t tsmb_type) > @@ -96,7 +100,7 @@ static void encode_styl(MovTextContext *s, > uint32_t tsmb_type) int j; > uint32_t tsmb_size; > uint16_t style_entries; > -if (s->box_flags & STYL_BOX) { > +if ((s->box_flags & STYL_BOX) && s->count) { > tsmb_size = s->count * STYLE_RECORD_SIZE + SIZE_ADD; > tsmb_size = AV_RB32(&tsmb_size); > style_entries = AV_RB16(&s->count); > @@ -120,8 +124,8 @@ static void encode_styl(MovTextContext *s, > uint32_t tsmb_type) av_bprint_append_any(&s->buffer, > &s->style_fontsize, 1); av_bprint_append_any(&s->buffer, > &s->style_color, 4); } > -mov_text_cleanup(s); > } > +mov_text_cleanup(s); > } > > static void encode_hlit(MovTextContext *s, uint32_t tsmb_type) > @@ -201,6 +205,11 @@ static av_cold int > mov_text_encode_init(AVCodecContext *avctx) MovTextContext *s = > avctx->priv_data; s->avctx = avctx; > > +s->style_attributes_temp = > av_mallocz(sizeof(*s->style_attributes_temp)); > +if (!s->style_attributes_temp) { > +return AVERROR(ENOMEM); > +} > + > avctx->extradata_size = sizeof text_sample_entry; > avctx->extradata = av_mallocz(avctx->extradata_size + > AV_INPUT_BUFFER_PADDING_SIZE); if (!avctx->extradata) > @@ -214,85 +223,69 @@ static av_cold int > mov_text_encode_init(AVCodecContext *avctx) return s->ass_ctx ? 0 : > AVERROR_INVALIDDATA; } > > -static void mov_text_style_cb(void *priv, const char style, int > close) +// Start a new style box if needed > +static int mov_text_style_start(MovTextContext *s) > { > -MovTextContext *s = priv; > -if (!close) { > -if (!(s->box_flags & STYL_BOX)) { //first style entry > - > -s->style_attributes_temp = > av_malloc(sizeof(*s->style_attributes_temp)); - > -if (!s->style_attributes_temp) { > -av_bprint_clear(&s->buffer); > -s->box_flags &= ~STYL_BOX; > -return; > -} > - > -s->style_attributes_temp->style_flag = 0; > -s->style_attributes_temp->style_start = s->text_pos; > -} else { > -if (s->style_attributes_temp->style_flag) { //break the > style record here and start a new one > -s->style_attributes_temp->style_end = s->text_pos; > -av_dynarray_add(&s->style_attributes, &s->count, > s->style_attributes_temp); > -s->style_attributes_temp = > av_malloc(sizeof(*s->style_attributes_temp)); > -if (!s->style_attributes_temp) { > -mov_text_cleanup(s); > -av_bprint_clear(&s->buffer); > -s->box_flags &= ~STYL_BOX; > -return; > -} > - > -s->style_attributes_temp->style_flag = > s->style_attributes[s->count - 1]->style_flag; > -s->style_attributes_temp->style_start = s->text_pos; > -} else { > -s->style_attributes_temp->style_flag = 0; > -s->style_attributes_temp->style_start = s->text_pos; > -} > -} > -switch (style){ > -case 'b': > -s->style_attributes_temp->style_flag |= STYLE_FLAG_BOLD; > -break; > -case 'i': > -s->style_attributes_temp->style_flag |= > STYLE_FLAG_ITALIC; > -break; > -case 'u': > -s->style_attributes_temp->style_flag |= > STYLE_FLAG_UNDERLINE; > -break; > -} > -} else if (!s->style_attributes_temp) { > -av_log(s->avctx, AV_LOG_WARNING, "Ignoring unmatched close > tag\n"); > -return; > -} else { > +// there's an existing style entry > +if (s->style_attributes_temp->style_start == s->text_pos) > +// Still at same text pos, use same entry > +return 1; > +if (s->style_attributes_temp->style_flag) { > +// last style != defaults, end the style entry and start a > new one > +s->box_flags |= STYL_BOX; > s->style_attributes_temp->style_end = s->text_pos; > av_dynarray_add(&s->style_attributes, &s->count, > s->style_attributes_temp); - > s->style_attributes_temp = > av
Re: [FFmpeg-devel] [PATCH 15/23] lavc/movtextenc: fix unclosed style records
On Mon, 6 Apr 2020 11:52:10 -0600 John Stebbins wrote: > The last record at the end of each dialog was never closed > --- > libavcodec/movtextenc.c | 7 +++ > 1 file changed, 7 insertions(+) > > diff --git a/libavcodec/movtextenc.c b/libavcodec/movtextenc.c > index 05532cd544..d389111419 100644 > --- a/libavcodec/movtextenc.c > +++ b/libavcodec/movtextenc.c > @@ -309,6 +309,12 @@ static void mov_text_color_cb(void *priv, > unsigned int color, unsigned int color */ > } > > +static void mov_text_end_cb(void *priv) > +{ > +// End of text, close any open style record > +mov_text_style_start((MovTextContext*)priv); > +} > + > static uint16_t utf8_strlen(const char *text, int len) > { > uint16_t i = 0, ret = 0; > @@ -352,6 +358,7 @@ static const ASSCodesCallbacks mov_text_callbacks > = { .new_line = mov_text_new_line_cb, > .style= mov_text_style_cb, > .color= mov_text_color_cb, > +.end = mov_text_end_cb, > }; > > static int mov_text_encode_frame(AVCodecContext *avctx, unsigned > char *buf, LGTM --phil ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH 10/23] lavc/movtextdec: allow setting subtitle frame dimensions
On Mon, 6 Apr 2020 11:52:05 -0600 John Stebbins wrote: > Font sizes are relative to the subtitle frame dimensions. If the > expected frame dimensions are not known, the font sizes will most > likely be incorrect. > --- > libavcodec/ass.c| 30 +++--- > libavcodec/ass.h| 28 > libavcodec/movtextdec.c | 30 +- > 3 files changed, 80 insertions(+), 8 deletions(-) > > diff --git a/libavcodec/ass.c b/libavcodec/ass.c > index a51673fb4e..7c26e3fd6d 100644 > --- a/libavcodec/ass.c > +++ b/libavcodec/ass.c > @@ -26,11 +26,13 @@ > #include "libavutil/bprint.h" > #include "libavutil/common.h" > > -int ff_ass_subtitle_header(AVCodecContext *avctx, > - const char *font, int font_size, > - int color, int back_color, > - int bold, int italic, int underline, > - int border_style, int alignment) > +int ff_ass_subtitle_header_full(AVCodecContext *avctx, > +int play_res_x, int play_res_y, > +const char *font, int font_size, > +int primary_color, int > secondary_color, > +int outline_color, int back_color, > +int bold, int italic, int underline, > +int border_style, int alignment) > { > avctx->subtitle_header = av_asprintf( > "[Script Info]\r\n" > @@ -67,8 +69,8 @@ int ff_ass_subtitle_header(AVCodecContext *avctx, > "[Events]\r\n" > "Format: Layer, Start, End, Style, Name, MarginL, > MarginR, MarginV, Effect, Text\r\n", !(avctx->flags & > AV_CODEC_FLAG_BITEXACT) ? AV_STRINGIFY(LIBAVCODEC_VERSION) : "", > - ASS_DEFAULT_PLAYRESX, ASS_DEFAULT_PLAYRESY, > - font, font_size, color, color, back_color, back_color, > + play_res_x, play_res_y, font, font_size, > + primary_color, secondary_color, outline_color, > back_color, -bold, -italic, -underline, border_style, alignment); > > if (!avctx->subtitle_header) > @@ -77,6 +79,20 @@ int ff_ass_subtitle_header(AVCodecContext *avctx, > return 0; > } > > +int ff_ass_subtitle_header(AVCodecContext *avctx, > + const char *font, int font_size, > + int color, int back_color, > + int bold, int italic, int underline, > + int border_style, int alignment) > +{ > +return ff_ass_subtitle_header_full(avctx, > + ASS_DEFAULT_PLAYRESX, > ASS_DEFAULT_PLAYRESY, > + font, font_size, color, color, > + back_color, back_color, > + bold, italic, underline, > + border_style, alignment); > +} > + > int ff_ass_subtitle_header_default(AVCodecContext *avctx) > { > return ff_ass_subtitle_header(avctx, ASS_DEFAULT_FONT, > diff --git a/libavcodec/ass.h b/libavcodec/ass.h > index 314b43b686..2c260e4e78 100644 > --- a/libavcodec/ass.h > +++ b/libavcodec/ass.h > @@ -47,6 +47,34 @@ typedef struct FFASSDecoderContext { > int readorder; > } FFASSDecoderContext; > > +/** > + * Generate a suitable AVCodecContext.subtitle_header for > SUBTITLE_ASS. > + * Can specify all fields explicitly > + * > + * @param avctx pointer to the AVCodecContext > + * @param play_res_x subtitle frame width > + * @param play_res_y subtitle frame height > + * @param font name of the default font face to use > + * @param font_size default font size to use > + * @param primary_color default text color to use (ABGR) > + * @param secondary_color default secondary text color to use (ABGR) > + * @param outline_color default outline color to use (ABGR) > + * @param back_color default background color to use (ABGR) > + * @param bold 1 for bold text, 0 for normal text > + * @param italic 1 for italic text, 0 for normal text > + * @param underline 1 for underline text, 0 for normal text > + * @param border_style 1 for outline, 3 for opaque box > + * @param alignment position of the text (left, center, top...), > defined after > + * the layout of the numpad (1-3 sub, 4-6 mid, 7-9 > top) > + * @return >= 0 on success otherwise an error code <0 > + */ > +int ff_ass_subtitle_header_full(AVCodecContext *avctx, > +int play_res_x, int play_res_y, > +const char *font, int font_size, > +int primary_color, int > secondary_color, > +int outline_color, int back_color, > +int bold, int italic, int underline, > +int border_style, int alignment); > /** > * Generate a suitable AVCodecContext.subtitl
Re: [FFmpeg-devel] [PATCH 11/23] lavc/ass_split: fix parsing utf8 scripts
On Mon, 6 Apr 2020 12:35:32 -0600 John Stebbins wrote: > The [Script Info] section was skipped if starts with UTF8 BOM > --- > libavcodec/ass_split.c | 2 ++ > 1 file changed, 2 insertions(+) > > diff --git a/libavcodec/ass_split.c b/libavcodec/ass_split.c > index 67da7c6d84..c2c388d9f0 100644 > --- a/libavcodec/ass_split.c > +++ b/libavcodec/ass_split.c > @@ -376,6 +376,8 @@ ASSSplitContext *ff_ass_split(const char *buf) > ASSSplitContext *ctx = av_mallocz(sizeof(*ctx)); > if (!ctx) > return NULL; > +if (buf && !memcmp(buf, "\xef\xbb\xbf", 3)) // Skip UTF-8 BOM > header > +buf += 3; > ctx->current_section = -1; > if (ass_split(ctx, buf) < 0) { > ff_ass_split_free(ctx); LGTM --phil ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH 16/23] lavc/movtextenc: init style record from ASS dialog style
On Mon, 6 Apr 2020 11:52:11 -0600 John Stebbins wrote: > --- > libavcodec/movtextenc.c | 60 > ++--- 1 file changed, 50 > insertions(+), 10 deletions(-) > > diff --git a/libavcodec/movtextenc.c b/libavcodec/movtextenc.c > index d389111419..4e7d55efcb 100644 > --- a/libavcodec/movtextenc.c > +++ b/libavcodec/movtextenc.c > @@ -39,6 +39,11 @@ > #define HLIT_BOX (1<<1) > #define HCLR_BOX (1<<2) > > +#define DEFAULT_STYLE_FONT_ID 0x01 > +#define DEFAULT_STYLE_FONTSIZE 0x12 > +#define DEFAULT_STYLE_COLOR0x > +#define DEFAULT_STYLE_FLAG 0x00 > + > #define BGR_TO_RGB(c) (((c) & 0xff) << 16 | ((c) & 0xff00) | (((c) > >> 16) & 0xff)) #define av_bprint_append_any(buf, data, size) > >> av_bprint_append_data(buf, ((const char*)data), size) > > @@ -46,6 +51,9 @@ typedef struct { > uint16_t style_start; > uint16_t style_end; > uint8_t style_flag; > +uint16_t style_fontID; > +uint8_t style_fontsize; > +uint32_t style_color; > } StyleBox; > > typedef struct { > @@ -68,9 +76,7 @@ typedef struct { > HilightcolorBox hclr; > int count; > uint8_t box_flags; > -uint16_t style_fontID; > -uint8_t style_fontsize; > -uint32_t style_color; > +StyleBox d; > uint16_t text_pos; > uint16_t byte_count; > } MovTextContext; > @@ -104,25 +110,26 @@ static void encode_styl(MovTextContext *s, > uint32_t tsmb_type) tsmb_size = s->count * STYLE_RECORD_SIZE + > SIZE_ADD; tsmb_size = AV_RB32(&tsmb_size); > style_entries = AV_RB16(&s->count); > -s->style_fontID = 0x00 | 0x01<<8; > -s->style_fontsize = 0x12; > -s->style_color = MKTAG(0xFF, 0xFF, 0xFF, 0xFF); > /*The above three attributes are hard coded for now > but will come from ASS style in the future*/ > av_bprint_append_any(&s->buffer, &tsmb_size, 4); > av_bprint_append_any(&s->buffer, &tsmb_type, 4); > av_bprint_append_any(&s->buffer, &style_entries, 2); > for (j = 0; j < s->count; j++) { > -uint16_t style_start, style_end; > +uint16_t style_start, style_end, style_fontID; > +uint32_t style_color; > > style_start = > AV_RB16(&s->style_attributes[j]->style_start); style_end= > AV_RB16(&s->style_attributes[j]->style_end); > +style_color = AV_RB32(&s->d.style_color); > +style_fontID = AV_RB16(&s->d.style_fontID); > + > av_bprint_append_any(&s->buffer, &style_start, 2); > av_bprint_append_any(&s->buffer, &style_end, 2); > -av_bprint_append_any(&s->buffer, &s->style_fontID, 2); > +av_bprint_append_any(&s->buffer, &style_fontID, 2); > av_bprint_append_any(&s->buffer, > &s->style_attributes[j]->style_flag, 1); > -av_bprint_append_any(&s->buffer, &s->style_fontsize, 1); > -av_bprint_append_any(&s->buffer, &s->style_color, 4); > +av_bprint_append_any(&s->buffer, &s->d.style_fontsize, > 1); > +av_bprint_append_any(&s->buffer, &style_color, 4); > } > } > mov_text_cleanup(s); > @@ -220,6 +227,13 @@ static av_cold int > mov_text_encode_init(AVCodecContext *avctx) memcpy(avctx->extradata, > text_sample_entry, avctx->extradata_size); > s->ass_ctx = ff_ass_split(avctx->subtitle_header); > + > +// TODO: Initialize from ASS style record > +s->d.style_fontID = DEFAULT_STYLE_FONT_ID; > +s->d.style_fontsize = DEFAULT_STYLE_FONTSIZE; > +s->d.style_color= DEFAULT_STYLE_COLOR; > +s->d.style_flag = DEFAULT_STYLE_FLAG; > + > return s->ass_ctx ? 0 : AVERROR_INVALIDDATA; > } > > @@ -270,6 +284,17 @@ static uint8_t mov_text_style_to_flag(const char > style) return style_flag; > } > > +static void mov_text_style_set(MovTextContext *s, uint8_t > style_flags) +{ > +if (!s->style_attributes_temp || > +!((s->style_attributes_temp->style_flag & style_flags) ^ > style_flags)) { > +// setting flags that that are already set > +return; > +} > +if (mov_text_style_start(s)) > +s->style_attributes_temp->style_flag |= style_flags; > +} > + > static void mov_text_style_cb(void *priv, const char style, int > close) { > MovTextContext *s = priv; > @@ -315,6 +340,19 @@ static void mov_text_end_cb(void *priv) > mov_text_style_start((MovTextContext*)priv); > } > > +static void mov_text_dialog(MovTextContext *s, ASSDialog *dialog) > +{ > +ASSStyle * style = ff_ass_style_get(s->ass_ctx, dialog->style); > +uint8_tstyle_flags; > + > +if (style) { > +style_flags = (!!style->bold * STYLE_FLAG_BOLD) | > + (!!style->italic* STYLE_FLAG_ITALIC) | > + (!!style->underline * STYLE_FLAG_UNDERLINE); > +mov_text_style_set(s, style_flags); > +} > +} > + > static uint16_t utf8_strlen(const char *text, int len) > { > uint16_t i =
Re: [FFmpeg-devel] [PATCH 17/23] lavc/movtextenc: add color tag handling
On Mon, 6 Apr 2020 11:52:12 -0600 John Stebbins wrote: > --- > libavcodec/movtextenc.c | 28 > 1 file changed, 24 insertions(+), 4 deletions(-) > > diff --git a/libavcodec/movtextenc.c b/libavcodec/movtextenc.c > index 4e7d55efcb..090536b887 100644 > --- a/libavcodec/movtextenc.c > +++ b/libavcodec/movtextenc.c > @@ -121,7 +121,7 @@ static void encode_styl(MovTextContext *s, > uint32_t tsmb_type) > style_start = > AV_RB16(&s->style_attributes[j]->style_start); style_end= > AV_RB16(&s->style_attributes[j]->style_end); > -style_color = AV_RB32(&s->d.style_color); > +style_color = > AV_RB32(&s->style_attributes[j]->style_color); style_fontID = > AV_RB16(&s->d.style_fontID); > av_bprint_append_any(&s->buffer, &style_start, 2); > @@ -244,7 +244,8 @@ static int mov_text_style_start(MovTextContext *s) > if (s->style_attributes_temp->style_start == s->text_pos) > // Still at same text pos, use same entry > return 1; > -if (s->style_attributes_temp->style_flag) { > +if (s->style_attributes_temp->style_flag != s->d.style_flag || > +s->style_attributes_temp->style_color != s->d.style_color) { > // last style != defaults, end the style entry and start a > new one s->box_flags |= STYL_BOX; > s->style_attributes_temp->style_end = s->text_pos; > @@ -258,9 +259,11 @@ static int mov_text_style_start(MovTextContext > *s) } > > s->style_attributes_temp->style_flag = > s->style_attributes[s->count - 1]->style_flag; > +s->style_attributes_temp->style_color = > s->style_attributes[s->count - 1]->style_color; > s->style_attributes_temp->style_start = s->text_pos; } else { // > style entry matches defaults, drop entry > -s->style_attributes_temp->style_flag = 0; > +s->style_attributes_temp->style_flag = s->d.style_flag; > +s->style_attributes_temp->style_color = s->d.style_color; > s->style_attributes_temp->style_start = s->text_pos; > } > return 1; > @@ -313,12 +316,26 @@ static void mov_text_style_cb(void *priv, const > char style, int close) } > } > > +static void mov_text_color_set(MovTextContext *s, uint32_t color) > +{ > +if (!s->style_attributes_temp || > +(s->style_attributes_temp->style_color & 0xff00) == > color) { > +// color hasn't changed > +return; > +} > +if (mov_text_style_start(s)) > +s->style_attributes_temp->style_color = (color & 0xff00) > | > +(s->style_attributes_temp->style_color & > 0xff); +} > + > static void mov_text_color_cb(void *priv, unsigned int color, > unsigned int color_id) { > MovTextContext *s = priv; > > color = BGR_TO_RGB(color) << 8; > -if (color_id == 2) {//secondary color changes > +if (color_id == 1) {//primary color changes > +mov_text_color_set(s, color); > +} else if (color_id == 2) {//secondary color changes > if (s->box_flags & HLIT_BOX) { //close tag > s->hlit.end = s->text_pos; > } else { > @@ -344,12 +361,15 @@ static void mov_text_dialog(MovTextContext *s, > ASSDialog *dialog) { > ASSStyle * style = ff_ass_style_get(s->ass_ctx, dialog->style); > uint8_tstyle_flags; > +uint32_t color; > > if (style) { > style_flags = (!!style->bold * STYLE_FLAG_BOLD) | >(!!style->italic* STYLE_FLAG_ITALIC) | >(!!style->underline * STYLE_FLAG_UNDERLINE); > mov_text_style_set(s, style_flags); > +color = BGR_TO_RGB(style->primary_color & 0xff) << 8; > +mov_text_color_set(s, color); > } > } > LGTM --phil ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH 18/23] lavc/movtextenc: add alpha tag handling
On Mon, 6 Apr 2020 11:52:13 -0600 John Stebbins wrote: > --- > libavcodec/movtextenc.c | 25 - > 1 file changed, 24 insertions(+), 1 deletion(-) > > diff --git a/libavcodec/movtextenc.c b/libavcodec/movtextenc.c > index 090536b887..e82393dde7 100644 > --- a/libavcodec/movtextenc.c > +++ b/libavcodec/movtextenc.c > @@ -351,6 +351,26 @@ static void mov_text_color_cb(void *priv, > unsigned int color, unsigned int color */ > } > > +static void mov_text_alpha_set(MovTextContext *s, uint8_t alpha) > +{ > +if (!s->style_attributes_temp || > +(s->style_attributes_temp->style_color & 0xff) == alpha) { > +// color hasn't changed > +return; > +} > +if (mov_text_style_start(s)) > +s->style_attributes_temp->style_color = > +(s->style_attributes_temp->style_color & 0xff00) > | alpha; +} > + > +static void mov_text_alpha_cb(void *priv, int alpha, int alpha_id) > +{ > +MovTextContext *s = priv; > + > +if (alpha_id == 1) // primary alpha changes > +mov_text_alpha_set(s, 255 - alpha); > +} Worth a comment that secondary alpha can't be preserved? > + > static void mov_text_end_cb(void *priv) > { > // End of text, close any open style record > @@ -360,7 +380,7 @@ static void mov_text_end_cb(void *priv) > static void mov_text_dialog(MovTextContext *s, ASSDialog *dialog) > { > ASSStyle * style = ff_ass_style_get(s->ass_ctx, dialog->style); > -uint8_tstyle_flags; > +uint8_tstyle_flags, alpha; > uint32_t color; > > if (style) { > @@ -370,6 +390,8 @@ static void mov_text_dialog(MovTextContext *s, > ASSDialog *dialog) mov_text_style_set(s, style_flags); > color = BGR_TO_RGB(style->primary_color & 0xff) << 8; > mov_text_color_set(s, color); > +alpha = 255 - ((uint32_t)style->primary_color >> 24); > +mov_text_alpha_set(s, alpha); > } > } > > @@ -416,6 +438,7 @@ static const ASSCodesCallbacks mov_text_callbacks > = { .new_line = mov_text_new_line_cb, > .style= mov_text_style_cb, > .color= mov_text_color_cb, > +.alpha= mov_text_alpha_cb, > .end = mov_text_end_cb, > }; > Otherwise LGTM. --phil ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH 19/23] lavc/movtextenc: add font size tag handling
On Mon, 6 Apr 2020 11:52:14 -0600 John Stebbins wrote: > --- > libavcodec/movtextenc.c | 39 ++- > 1 file changed, 30 insertions(+), 9 deletions(-) > > diff --git a/libavcodec/movtextenc.c b/libavcodec/movtextenc.c > index e82393dde7..9e657c9635 100644 > --- a/libavcodec/movtextenc.c > +++ b/libavcodec/movtextenc.c > @@ -128,7 +128,7 @@ static void encode_styl(MovTextContext *s, > uint32_t tsmb_type) av_bprint_append_any(&s->buffer, &style_end, 2); > av_bprint_append_any(&s->buffer, &style_fontID, 2); > av_bprint_append_any(&s->buffer, > &s->style_attributes[j]->style_flag, 1); > -av_bprint_append_any(&s->buffer, &s->d.style_fontsize, > 1); > +av_bprint_append_any(&s->buffer, > &s->style_attributes[j]->style_fontsize, 1); > av_bprint_append_any(&s->buffer, &style_color, 4); } > } > @@ -244,8 +244,9 @@ static int mov_text_style_start(MovTextContext *s) > if (s->style_attributes_temp->style_start == s->text_pos) > // Still at same text pos, use same entry > return 1; > -if (s->style_attributes_temp->style_flag != s->d.style_flag || > -s->style_attributes_temp->style_color != s->d.style_color) { > +if (s->style_attributes_temp->style_flag != s->d.style_flag > || > +s->style_attributes_temp->style_color!= s->d.style_color > || > +s->style_attributes_temp->style_fontsize != > s->d.style_fontsize) { // last style != defaults, end the style entry > and start a new one s->box_flags |= STYL_BOX; > s->style_attributes_temp->style_end = s->text_pos; > @@ -260,10 +261,12 @@ static int mov_text_style_start(MovTextContext > *s) > s->style_attributes_temp->style_flag = > s->style_attributes[s->count - 1]->style_flag; > s->style_attributes_temp->style_color = s->style_attributes[s->count > - 1]->style_color; > +s->style_attributes_temp->style_fontsize = > s->style_attributes[s->count - 1]->style_fontsize; > s->style_attributes_temp->style_start = s->text_pos; } else { // > style entry matches defaults, drop entry > s->style_attributes_temp->style_flag = s->d.style_flag; > s->style_attributes_temp->style_color = s->d.style_color; > +s->style_attributes_temp->style_fontsize = > s->d.style_fontsize; s->style_attributes_temp->style_start = > s->text_pos; } > return 1; > @@ -371,6 +374,22 @@ static void mov_text_alpha_cb(void *priv, int > alpha, int alpha_id) mov_text_alpha_set(s, 255 - alpha); > } > > +static void mov_text_font_size_set(MovTextContext *s, int size) > +{ > +if (!s->style_attributes_temp || > +s->style_attributes_temp->style_fontsize == size) { > +// color hasn't changed > +return; > +} > +if (mov_text_style_start(s)) > +s->style_attributes_temp->style_fontsize = size; > +} > + > +static void mov_text_font_size_cb(void *priv, int size) > +{ > +mov_text_font_size_set((MovTextContext*)priv, size); > +} > + > static void mov_text_end_cb(void *priv) > { > // End of text, close any open style record > @@ -392,6 +411,7 @@ static void mov_text_dialog(MovTextContext *s, > ASSDialog *dialog) mov_text_color_set(s, color); > alpha = 255 - ((uint32_t)style->primary_color >> 24); > mov_text_alpha_set(s, alpha); > +mov_text_font_size_set(s, style->font_size); > } > } > > @@ -434,12 +454,13 @@ static void mov_text_new_line_cb(void *priv, > int forced) } > > static const ASSCodesCallbacks mov_text_callbacks = { > -.text = mov_text_text_cb, > -.new_line = mov_text_new_line_cb, > -.style= mov_text_style_cb, > -.color= mov_text_color_cb, > -.alpha= mov_text_alpha_cb, > -.end = mov_text_end_cb, > +.text = mov_text_text_cb, > +.new_line = mov_text_new_line_cb, > +.style = mov_text_style_cb, > +.color = mov_text_color_cb, > +.alpha = mov_text_alpha_cb, > +.font_size = mov_text_font_size_cb, > +.end = mov_text_end_cb, > }; > > static int mov_text_encode_frame(AVCodecContext *avctx, unsigned > char *buf, LGTM --phil ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH 20/23] lavc/movtextenc: handle cancel overrides callback
On Tue, 7 Apr 2020 09:00:34 -0600 John Stebbins wrote: > --- > libavcodec/movtextenc.c | 43 > - 1 file changed, 34 > insertions(+), 9 deletions(-) > > diff --git a/libavcodec/movtextenc.c b/libavcodec/movtextenc.c > index 9e657c9635..2d3c416407 100644 > --- a/libavcodec/movtextenc.c > +++ b/libavcodec/movtextenc.c > @@ -69,6 +69,7 @@ typedef struct { > AVCodecContext *avctx; > > ASSSplitContext *ass_ctx; > +ASSStyle *ass_dialog_style; > AVBPrint buffer; > StyleBox **style_attributes; > StyleBox *style_attributes_temp; > @@ -396,9 +397,8 @@ static void mov_text_end_cb(void *priv) > mov_text_style_start((MovTextContext*)priv); > } > > -static void mov_text_dialog(MovTextContext *s, ASSDialog *dialog) > +static void mov_text_ass_style_set(MovTextContext *s, ASSStyle > *style) { > -ASSStyle * style = ff_ass_style_get(s->ass_ctx, dialog->style); > uint8_tstyle_flags, alpha; > uint32_t color; > > @@ -412,9 +412,33 @@ static void mov_text_dialog(MovTextContext *s, > ASSDialog *dialog) alpha = 255 - ((uint32_t)style->primary_color >> > 24); mov_text_alpha_set(s, alpha); > mov_text_font_size_set(s, style->font_size); > +} else { > +// End current style record, go back to defaults > +mov_text_style_start(s); > } > } > > +static void mov_text_dialog(MovTextContext *s, ASSDialog *dialog) > +{ > +ASSStyle * style = ff_ass_style_get(s->ass_ctx, dialog->style); > + > +s->ass_dialog_style = style; > +mov_text_ass_style_set(s, style); > +} > + > +static void mov_text_cancel_overrides_cb(void *priv, const char * > style_name) +{ > +MovTextContext *s = priv; > +ASSStyle * style; > + > +if (!style_name || !*style_name) > +style = s->ass_dialog_style; > +else > +style= ff_ass_style_get(s->ass_ctx, style_name); > + > +mov_text_ass_style_set(s, style); > +} > + > static uint16_t utf8_strlen(const char *text, int len) > { > uint16_t i = 0, ret = 0; > @@ -454,13 +478,14 @@ static void mov_text_new_line_cb(void *priv, > int forced) } > > static const ASSCodesCallbacks mov_text_callbacks = { > -.text = mov_text_text_cb, > -.new_line = mov_text_new_line_cb, > -.style = mov_text_style_cb, > -.color = mov_text_color_cb, > -.alpha = mov_text_alpha_cb, > -.font_size = mov_text_font_size_cb, > -.end = mov_text_end_cb, > +.text = mov_text_text_cb, > +.new_line = mov_text_new_line_cb, > +.style= mov_text_style_cb, > +.color= mov_text_color_cb, > +.alpha= mov_text_alpha_cb, > +.font_size= mov_text_font_size_cb, > +.cancel_overrides = mov_text_cancel_overrides_cb, > +.end = mov_text_end_cb, > }; > > static int mov_text_encode_frame(AVCodecContext *avctx, unsigned > char *buf, LGTM --phil ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH 21/23] lavc/movtextenc: simplify initialization of new style record
On Mon, 6 Apr 2020 11:52:16 -0600 John Stebbins wrote: > --- > libavcodec/movtextenc.c | 13 - > 1 file changed, 4 insertions(+), 9 deletions(-) > > diff --git a/libavcodec/movtextenc.c b/libavcodec/movtextenc.c > index 2e65489c4d..167dffee6a 100644 > --- a/libavcodec/movtextenc.c > +++ b/libavcodec/movtextenc.c > @@ -96,8 +96,7 @@ static void mov_text_cleanup(MovTextContext *s) > av_freep(&s->style_attributes); > } > if (s->style_attributes_temp) { > -s->style_attributes_temp->style_flag = 0; > -s->style_attributes_temp->style_start = 0; > +*s->style_attributes_temp = s->d; > } > } > > @@ -122,7 +121,7 @@ static void encode_styl(MovTextContext *s, > uint32_t tsmb_type) style_start = > AV_RB16(&s->style_attributes[j]->style_start); style_end= > AV_RB16(&s->style_attributes[j]->style_end); style_color = > AV_RB32(&s->style_attributes[j]->style_color); > -style_fontID = AV_RB16(&s->d.style_fontID); > +style_fontID = > AV_RB16(&s->style_attributes[j]->style_fontID); > av_bprint_append_any(&s->buffer, &style_start, 2); > av_bprint_append_any(&s->buffer, &style_end, 2); > @@ -259,14 +258,10 @@ static int mov_text_style_start(MovTextContext > *s) return 0; > } > > -s->style_attributes_temp->style_flag = > s->style_attributes[s->count - 1]->style_flag; > -s->style_attributes_temp->style_color = > s->style_attributes[s->count - 1]->style_color; > -s->style_attributes_temp->style_fontsize = > s->style_attributes[s->count - 1]->style_fontsize; > +*s->style_attributes_temp = s->d; > s->style_attributes_temp->style_start = s->text_pos; > } else { // style entry matches defaults, drop entry > -s->style_attributes_temp->style_flag = s->d.style_flag; > -s->style_attributes_temp->style_color = s->d.style_color; > -s->style_attributes_temp->style_fontsize = > s->d.style_fontsize; > +*s->style_attributes_temp = s->d; > s->style_attributes_temp->style_start = s->text_pos; > } > return 1; LGTM --phil ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH 23/23] lavc/movtextenc: add option to scale fontsize with height
On Mon, 6 Apr 2020 11:52:18 -0600 John Stebbins wrote: > If the video dimensions are different than the ASS play_res then the > font sizes need to be adjusted to get the same apparent render size. > --- > libavcodec/movtextenc.c | 30 +- > 1 file changed, 29 insertions(+), 1 deletion(-) > > diff --git a/libavcodec/movtextenc.c b/libavcodec/movtextenc.c > index a62bdb7eb0..3d4371b180 100644 > --- a/libavcodec/movtextenc.c > +++ b/libavcodec/movtextenc.c > @@ -21,6 +21,7 @@ > > #include > #include "avcodec.h" > +#include "libavutil/opt.h" > #include "libavutil/avassert.h" > #include "libavutil/avstring.h" > #include "libavutil/intreadwrite.h" > @@ -45,6 +46,7 @@ > #define DEFAULT_STYLE_FLAG 0x00 > > #define BGR_TO_RGB(c) (((c) & 0xff) << 16 | ((c) & 0xff00) | (((c) > >> 16) & 0xff)) +#define FONTSIZE_SCALE(s,fs) ((fs) * > >> (s)->font_scale_factor + 0.5) > #define av_bprint_append_any(buf, data, size) > av_bprint_append_data(buf, ((const char*)data), size) > typedef struct { > @@ -66,6 +68,7 @@ typedef struct { > } HilightcolorBox; > > typedef struct { > +AVClass *class; > AVCodecContext *avctx; > > ASSSplitContext *ass_ctx; > @@ -81,6 +84,8 @@ typedef struct { > uint16_t byte_count; > char ** fonts; > int font_count; > +double font_scale_factor; > +int frame_height; > } MovTextContext; > > typedef struct { > @@ -236,6 +241,13 @@ static int > encode_sample_description(AVCodecContext *avctx) > // Populate sample description from ASS header > ass = ff_ass_get(s->ass_ctx); > +// Compute font scaling factor based on (optionally) provided > +// output video height and ASS script play_res_y > +if (s->frame_height && ass->script_info.play_res_y) > +s->font_scale_factor = (double)s->frame_height / > ass->script_info.play_res_y; > +else > +s->font_scale_factor = 1; > + > style = ff_ass_style_get(s->ass_ctx, "Default"); > if (!style && ass->styles_count) { > style = &ass->styles[0]; > @@ -245,7 +257,7 @@ static int > encode_sample_description(AVCodecContext *avctx) s->d.style_color > = DEFAULT_STYLE_COLOR; s->d.style_flag = DEFAULT_STYLE_FLAG; > if (style) { > -s->d.style_fontsize = style->font_size; > +s->d.style_fontsize = FONTSIZE_SCALE(s, style->font_size); > s->d.style_color = BGR_TO_RGB(style->primary_color & > 0xff) << 8 | 255 - ((uint32_t)style->primary_color >> 24); > s->d.style_flag = (!!style->bold * STYLE_FLAG_BOLD) | > @@ -530,6 +542,7 @@ static void mov_text_font_name_cb(void *priv, > const char *name) > static void mov_text_font_size_set(MovTextContext *s, int size) > { > +size = FONTSIZE_SCALE(s, size); > if (!s->style_attributes_temp || > s->style_attributes_temp->style_fontsize == size) { > // color hasn't changed > @@ -709,12 +722,27 @@ exit: > return length; > } > > +#define OFFSET(x) offsetof(MovTextContext, x) > +#define FLAGS AV_OPT_FLAG_ENCODING_PARAM | AV_OPT_FLAG_SUBTITLE_PARAM > +static const AVOption options[] = { > +{ "height", "Frame height, usually video height", > OFFSET(frame_height), AV_OPT_TYPE_INT, {.i64=0}, 0, INT_MAX, FLAGS }, > +{ NULL }, > +}; > + > +static const AVClass mov_text_encoder_class = { > +.class_name = "MOV text enoder", > +.item_name = av_default_item_name, > +.option = options, > +.version= LIBAVUTIL_VERSION_INT, > +}; > + > AVCodec ff_movtext_encoder = { > .name = "mov_text", > .long_name = NULL_IF_CONFIG_SMALL("3GPP Timed Text > subtitle"), .type = AVMEDIA_TYPE_SUBTITLE, > .id = AV_CODEC_ID_MOV_TEXT, > .priv_data_size = sizeof(MovTextContext), > +.priv_class = &mov_text_encoder_class, > .init = mov_text_encode_init, > .encode_sub = mov_text_encode_frame, > .close = mov_text_encode_close, LGTM. --phil ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH 22/23] lavc/movtextenc: add font name handling
On Mon, 6 Apr 2020 11:52:17 -0600 John Stebbins wrote: > Initializes the mov text sample description from the ASS header and > creates an mov font table from the fonts available in the ASS Styles. > --- > libavcodec/ass_split.c | 5 + > libavcodec/ass_split.h | 8 ++ > libavcodec/movtextenc.c | 253 > 3 files changed, 216 > insertions(+), 50 deletions(-) > > diff --git a/libavcodec/ass_split.c b/libavcodec/ass_split.c > index 94c32667af..9d5a66f931 100644 > --- a/libavcodec/ass_split.c > +++ b/libavcodec/ass_split.c > @@ -599,3 +599,8 @@ ASSStyle *ff_ass_style_get(ASSSplitContext *ctx, > const char *style) return ass->styles + i; > return NULL; > } > + > +ASS *ff_ass_get(ASSSplitContext *ctx) > +{ > +return &ctx->ass; > +} > diff --git a/libavcodec/ass_split.h b/libavcodec/ass_split.h > index 30ce77250c..31b8e53242 100644 > --- a/libavcodec/ass_split.h > +++ b/libavcodec/ass_split.h > @@ -204,4 +204,12 @@ int ff_ass_split_override_codes(const > ASSCodesCallbacks *callbacks, void *priv, */ > ASSStyle *ff_ass_style_get(ASSSplitContext *ctx, const char *style); > > +/** > + * Get ASS structure > + * > + * @param ctx Context previously initialized by ff_ass_split(). > + * @return the ASS > + */ > +ASS *ff_ass_get(ASSSplitContext *ctx); Is this necesssary? The header says: /** * This struct can be casted to ASS to access to the split data. */ typedef struct ASSSplitContext ASSSplitContext; So can't you just cast the context you already have? > + > #endif /* AVCODEC_ASS_SPLIT_H */ > diff --git a/libavcodec/movtextenc.c b/libavcodec/movtextenc.c > index 167dffee6a..a62bdb7eb0 100644 > --- a/libavcodec/movtextenc.c > +++ b/libavcodec/movtextenc.c > @@ -79,6 +79,8 @@ typedef struct { > StyleBox d; > uint16_t text_pos; > uint16_t byte_count; > +char ** fonts; > +int font_count; > } MovTextContext; > > typedef struct { > @@ -171,69 +173,198 @@ static const Box box_types[] = { > > const static size_t box_count = FF_ARRAY_ELEMS(box_types); > > -static av_cold int mov_text_encode_init(AVCodecContext *avctx) > +static int mov_text_encode_close(AVCodecContext *avctx) > { > -/* > - * For now, we'll use a fixed default style. When we add styling > - * support, this will be generated from the ASS style. > - */ > -static const uint8_t text_sample_entry[] = { > +MovTextContext *s = avctx->priv_data; > +int i; > + > +ff_ass_split_free(s->ass_ctx); > +if (s->style_attributes) { > +for (i = 0; i < s->count; i++) { > +av_freep(&s->style_attributes[i]); > +} > +av_freep(&s->style_attributes); > +} > +av_freep(&s->fonts); > +av_freep(&s->style_attributes_temp); > +av_bprint_finalize(&s->buffer, NULL); > +return 0; > +} > + > +static int encode_sample_description(AVCodecContext *avctx) > +{ > +ASS * ass; > +ASSStyle * style; > +int i, j; > +uint32_t tsmb_size, tsmb_type, back_color, style_color; > +uint16_t style_start, style_end, fontID, count; > +int font_names_total_len = 0; > +MovTextContext *s = avctx->priv_data; > + > +static const uint8_t display_and_justification[] = { > 0x00, 0x00, 0x00, 0x00, // uint32_t displayFlags > 0x01, // int8_t horizontal-justification > 0xFF, // int8_t vertical-justification > -0x00, 0x00, 0x00, 0x00, // uint8_t background-color-rgba[4] > -// BoxRecord { > +}; > +// 0x00, 0x00, 0x00, 0x00, // uint8_t background-color-rgba[4] Is this right? Should it be un-commented or removed entirely? > +static const uint8_t box_record[] = { > +// BoxRecord { > 0x00, 0x00, // int16_t top > 0x00, 0x00, // int16_t left > 0x00, 0x00, // int16_t bottom > 0x00, 0x00, // int16_t right > -// }; > -// StyleRecord { > -0x00, 0x00, // uint16_t startChar > -0x00, 0x00, // uint16_t endChar > -0x00, 0x01, // uint16_t font-ID > -0x00, // uint8_t face-style-flags > -0x12, // uint8_t font-size > -0xFF, 0xFF, 0xFF, 0xFF, // uint8_t text-color-rgba[4] > -// }; > -// FontTableBox { > -0x00, 0x00, 0x00, 0x12, // uint32_t size > -'f', 't', 'a', 'b', // uint8_t name[4] > -0x00, 0x01, // uint16_t entry-count > -// FontRecord { > -0x00, 0x01, // uint16_t font-ID > -0x05, // uint8_t font-name-length > -'S', 'e', 'r', 'i', 'f',// uint8_t font[font-name-length] > -// }; > -// }; > +// }; > }; > +// StyleRecord { > +// 0x00, 0x00, // uint16_t startChar > +// 0x00, 0x00, // uint16_t endChar > +// 0x00, 0x01,
Re: [FFmpeg-devel] movtext decode/encode improvements
On Tue, 7 Apr 2020 14:38:52 + John Stebbins wrote: > > After checking carefully, patches 10 and 23 are as I want them. Sizes > are relative to 288 when using override APIs, but are relative to > PlayResY when processing the script. > > On the other hand, patch 20 needs a fix. If the cancel overrides does > not specify a style, it *should* restore the ASS style of the current > dialog, but instead it is returning to the mp4 default style. Thanks. I've gone through them all, and I've only had a few minor comments. Will you need me to push these once they are finalised? --phil ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH] avcodec/nvenc: adapt to the new internal encode API
On Wed, 8 Apr 2020 14:58:36 -0300 James Almer wrote: > Signed-off-by: James Almer > --- > This removes the encode2() implementation as it'll never be used if a > receive_packet() one exists, and the flush() implementation since > according to Anton Khirnov avcodec_flush_buffers() is not meant to be > used with encoders, where its behavior is undefined. Nevertheless, there is a use case for flushing an encoder (see 3ea705), and when you call avcodec_flush_buffers() in nvenc, it does the right thing. Removing this will return us to the world before that change where there was no way to flush the encoder, and the original bug reporter was asking about adding an API to do it. It seems the right thing to do is to define the behaviour - which seems reasonable as-is today and documment that encoders can implement flush if necessary. Or we'll just end up adding a new API that flushes encoders but has a different name... --phil ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH 01/23] lavc/movtextdec: fix ass header colors
On Thu, 9 Apr 2020 15:09:45 + John Stebbins wrote: > > > > I missed this review earlier. What about the indentation is off? Do > you mean the indent of the function parameters does not align after > the opening paren? I was keeping the lines aligned without wrapping > at 80 characters. Yes, I believe he's referring to the function parameters and not the overall indent. I would normally align to the paren. I think you can do that and keep under 80 if you put each one on its own line? --phil ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH] avcodec/nvenc: adapt to the new internal encode API
On Thu, 9 Apr 2020 11:20:09 -0300 James Almer wrote: > On 4/8/2020 7:04 PM, Philip Langdale wrote: > > On Wed, 8 Apr 2020 14:58:36 -0300 > > James Almer wrote: > > > >> Signed-off-by: James Almer > >> --- > >> This removes the encode2() implementation as it'll never be used > >> if a receive_packet() one exists, and the flush() implementation > >> since according to Anton Khirnov avcodec_flush_buffers() is not > >> meant to be used with encoders, where its behavior is undefined. > > > > Nevertheless, there is a use case for flushing an encoder (see > > 3ea705), and when you call avcodec_flush_buffers() in nvenc, it > > does the right thing. > > > > Removing this will return us to the world before that change where > > there was no way to flush the encoder, and the original bug reporter > > was asking about adding an API to do it. > > > > It seems the right thing to do is to define the behaviour - which > > seems reasonable as-is today and documment that encoders can > > implement flush if necessary. Or we'll just end up adding a new API > > that flushes encoders but has a different name... > > > > --phil > > I'm not against it, but as Marton said the function as it is is not > enough. The changes Anton asked me to remove would need to be re-added > (trivial to do), and the threading related code would probably need > some changes, if anything to not call decoding specific functions on > an encoder context. > > I like the codec capabilities suggestion from Marton. Could you look > into it? I'll change this patch to not remove the flush call while at > it. Yes, please leave the flush as-is for now so we don't regress. At the very least I think adding an encoder vs decoder path into the function makes sense and we can skip all the decoder specific parts. Today, the emergent behaviour is that an encoder is only affected by the flush call if it provides a flush callback - none of the other parts will alter its state, so perhaps the simple thing to do is have the encoder path just call the callback if it's there and naturally do nothing if not. That removes the need for a separate capability flag. --phil ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH 18/23] lavc/movtextenc: add alpha tag handling
On Thu, 9 Apr 2020 16:17:21 + John Stebbins wrote: > > > > > > Worth a comment that secondary alpha can't be preserved? > > > > Sure, will do. > > Taking a second look at this, I'm wondering if alpha_id = 2 should be > applied to the highlight color that is set in mov_text_color_cb? And > if so, should a highlight box be started if only the alpha is changed > and not the color? And if so, should the highlight color default to > the current primary color when only alpha changes? I'm not familiar > with how mov text highlight works and what it looks like in practice. > Do you have an opinion? > > If I add the above, I'll do that as a separate new patch, along with > the comment below. > > There should still be a comment here (and probably for color as well) > that outline and background colors can not be modified in mov text. I'm afraid I don't know either. I've not encountered any truly rich movtext subtitles so I don't know what these things are supposed to look like. It sounds like a reasonable argument to say you can apply an alpha-only highlight, but I couldn't even say if that's in-spec or not. :-) I agree that handling anything like that can be a separate patch. --phil ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH 22/23] lavc/movtextenc: add font name handling
On Thu, 9 Apr 2020 15:21:35 + John Stebbins wrote: > Well, I was leaving that in as a comment showing the structure of the > sample description. But if it's confusing, I can just remove all > those comments. There are several others that do not represent the > actual values written. Ok. That's fine. It was just a bit confusing to read in the diff. I can see the value in keeping the comments to document the structure. --phil ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] movtext decode/encode improvements
On Thu, 9 Apr 2020 15:51:23 + John Stebbins wrote: > On Wed, 2020-04-08 at 12:24 -0700, Philip Langdale wrote: > > On Tue, 7 Apr 2020 14:38:52 + > > John Stebbins wrote: > > > > > After checking carefully, patches 10 and 23 are as I want them. > > > Sizes > > > are relative to 288 when using override APIs, but are relative to > > > PlayResY when processing the script. > > > > > > On the other hand, patch 20 needs a fix. If the cancel overrides > > > does > > > not specify a style, it *should* restore the ASS style of the > > > current > > > dialog, but instead it is returning to the mp4 default style. > > > > Thanks. I've gone through them all, and I've only had a few minor > > comments. Will you need me to push these once they are finalised? > > > > > > Thanks to you as well. > > Yes, when we're all finished with reviews please commit. I don't have > commit access. I have a few comments by you to resolve (patches 18 > and 22) and one by Nicolas regarding indentation in patch 1. > > If I have to change the indentation in patch 1, it'll percolate > through a few other patches that touch the same code. So I'll have > to resend those, or I can just fix the indentation as a final patch > on top? > Looks like the indentation change is localised so shouldn't have a big effect. Can you push a branch to your github when you are ready - it'll be a lot easier for me to manage than grabbing these from email. Thanks, --phil ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] movtext decode/encode improvements
On Thu, 9 Apr 2020 19:30:53 + John Stebbins wrote: > > Pushed to https://github.com/jstebbins/FFmpeg/commits/movtext > > There's one additional patch on the top implementing what we discussed > about highlight alpha updates. Should I send that to the ml as well? > The new one looks good too, so I will merge it along with the others. Thanks for all of this work! It's a big set of improvements for the movtext handling! I'm guessing the motivation was to be able to switch Handbrake to using these instead of some other library? --phil ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] movtext decode/encode improvements
On Thu, 9 Apr 2020 23:28:49 + John Stebbins wrote: > Essentially yes. We've had our own mov text encoder and decoder in > HandBrake for years. I added support for using ffmpeg for decoding > subtitles last year but the movtext decoder wasn't up to the same > level as ours, so we weren't using ffmpeg for that yet. I'm following > up that work from last year to add subtitle encoding with ffmpeg and > dropping our decoder and encoder for mov text. That's great - and I really appreciate you taking the extra effort to feed this back! Of course, I can't help but be greedy: Have you looked at subtitle positioning? I think that's the biggest functional gap left. > I'm also almost finished writing a PGS subtitle encoder for ffmpeg ;) Very nice! --phil ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".