Re: [FFmpeg-devel] Flushing while decoding , but need already decoded frames

2024-05-24 Thread Andrey Turkin
Have to say, this issue has been a long grievance of mine. There is no
reason to delay frames when the decoder is set up to ignore B frames
as there is no reordering to be done; ideally this should be
zero-delay case (packet goes in, frame goes out) yet the most common
decoders delay frames anyway, as if to decode B frames. Moreover, with
the "new" send/receive API I think there is no reason to delay frames
at all - a single send_packet could decode and queue multiple frames
to be received, so it makes sense to send frames as soon as possible -
yet that is not the case as well.

пт, 24 мая 2024 г. в 13:17, Andreas Rheinhardt :
>
> Michael Henrik Bodenhoff via ffmpeg-devel:
> > Hi ,
> >
> > my team recently had to abandon switching to using FFmpeg from specific 
> > decoder implementations (NvDEC, Intel Media SDK , IPP and quite a few codec 
> > specific decoders) because of big performance issues because of the way 
> > FFmpeg works….. or at least we think it is (we’re FFmpeg noobs   )
> >
> > It's actually an issue we also had with Intel Media SDK,  leading us to pay 
> > Intel to extend Media SDK to do what we needed.
> >
> > Our product is a video surveillance system, and that means we have to 
> > decode a LOT of video streams simultaneously.
> >
> > For motion detection we want to only decode keyframes, and skip P and B 
> > frames , and that works fine with FFmpeg most of the time, except for when 
> > the video stream contains B frames.
> > Without B-Frames it’s really simple (simplified pseudocode) :
> >
> > while(true)
> > {
> >   receiveStreamCompleteFrame();
> >   If(KeyFrame)
> >   {
> > avcodec_send_packet();
> > if(avcodec_receive_frame()==0)
> > {
> >// do motion detection
> > }
> >   }
> > }
> >
> > But! with B Frames FFmpeg doesn’t return keyframes when they are decoded, 
> > they are kept, and we can’t seem to flush them out. avcodec_flush_buffers 
> > allow us to continue to next keyframe, but it doesn’t seem to give us the 
> > keyframe we just gave to FFmpeg with avcodec_send_packet.
> >
> > while(true)
> > {
> >   receiveStreamCompleteFrame();
> >   If(KeyFrame)
> >   {
> > avcodec_send_packet();
> > if(avcodec_receive_frame()==0)
> > {
> >// do motion detection
> > }
> > Else
> > {
> >   avcodec_flush_buffers();
> >   if(avcodec_receive_frame()==0)
> >   {
> >  // do motion detection
> >   }
> > }
> >   }
> > }
> >
> > Calling avcodec_receive_frame after calling avcodec_flush_buffer results in 
> > -11 and no frame
> >
> > is there anyway around this ? And if not, could FFmpeg be made to have this 
> > functionality ?
> >
> > I tried contacting one of the FFmpeg consultants from 
> > https://ffmpeg.org/consulting.html but never got a response
> >
>
> Send your packet with the keyframe, send a NULL packet (to signal EOF),
> then the internally stored frames should be output by
> avcodec_receive_frame(). Then flush the decoder (to be able to send new
> packets to it).
>
> - Andreas
>
> ___
> 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 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] What is FFmpeg and what should it be

2023-07-30 Thread Andrey Turkin
вс, 30 июл. 2023 г. в 16:04, Nicolas George :

> Kieran Kunhya (12023-07-28):
> > FFmpeg doesn't implement TCP in userspace, it doesn't implement the
> > WiFi protocol etc etc. Different layers are delegated to different
> > programs.
>

There is a good reason to have some part of TCP implemented in FFmpeg
though. It would be _extremely_ useful to be able to read and replay pcap
dumps of an RTP stream, or an HLS or DASH stream, or whichever else
multi-connection streams are there.
There is also at least one demodulator already in FFmpeg, namely VBI bit
slicer (it is implemented through an external library though).
___
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] libavformat: add multiple PCR streams in MPEGTS muxer

2018-10-29 Thread Andrey Turkin
This looks like a (strange) hack to me.
First, you cannot just throw some pids out - that will make a non-standard
compliant stream. PMT will signal missing streams; PCR pid will be missing
also. So let's assume that your tool can also rewrite PMT.
Secondly, there is supposed to be one and only one PCR stream per program;
there is no way to signal multiple PCRs. So let's assume you have some
out-of-band list of PCRs for this particular case (or maybe you can just
assume there are PCR marks in each stream so you can configure your remuxer
accordingly).
Thirdly and most importantly, I might be wrong here but it looks like your
patch just "spreads" same PCRs which would go into single stream over all
program's streams, i.e. overall PCR count doesn't change. Which means that
remuxed stream might have arbitrarily large inter-PCR gaps which is pretty
bad (assuming you care about PCRs at all, which presumably you do).

Also - do you really have multiple audio streams in single program, which
are supposed to be remuxed as separate radio channels? Or same for multiple
video streams? Is this for ABR purposes? Can you describe your use case in
some more details?

пн, 29 окт. 2018 г. в 4:20, :

> From 44c9f3d96c5969349bd2dc4d63e9a8b8e6b5a0e2 Mon Sep 17 00:00:00 2001
> From: M. Sanders 
> Date: Sat, 27 Oct 2018 21:39:44 +0200
> Subject: [PATCH] libavformat: add multiple PCR streams in MPEGTS muxer
>
> ---
> This simple patch adds two new options to the MPEG-TS muxer.
> You can use them to mark PCRs in additional VIDEO and/or AUDIO streams.
> It's useful when you will remux the output with pid filtering tools.
> For example, if you put PCR in all audio streams, then you can filter
> each audio stream to create a radio service.
> PCR marks do not disturb outgoing stream, but it is not recommended
> to do so as a regular rule.
>
>  doc/muxers.texi |  6 ++
>  libavformat/mpegtsenc.c | 19 +--
>  2 files changed, 23 insertions(+), 2 deletions(-)
>
> diff --git a/doc/muxers.texi b/doc/muxers.texi
> index f18543e83d..328707d0ed 100644
> --- a/doc/muxers.texi
> +++ b/doc/muxers.texi
> @@ -1528,6 +1528,12 @@ is @code{-1}, which results in shifting timestamps
> so that they start from 0.
>  @item omit_video_pes_length @var{boolean}
>  Omit the PES packet length for video packets. Default is @code{1} (true).
>
> +@item pcr_all_video @var{boolean}
> +Include PCR values in all video streams. Default is @code{0} (false).
> +
> +@item pcr_all_audio @var{boolean}
> +Include PCR values in all audio streams. Default is @code{0} (false).
> +
>  @item pcr_period @var{integer}
>  Override the default PCR retransmission time in milliseconds. Ignored if
>  variable muxrate is selected. Default is @code{20}.
> diff --git a/libavformat/mpegtsenc.c b/libavformat/mpegtsenc.c
> index 3339e26d50..caef817a3d 100644
> --- a/libavformat/mpegtsenc.c
> +++ b/libavformat/mpegtsenc.c
> @@ -113,6 +113,8 @@ typedef struct MpegTSWrite {
>  double sdt_period;
>  int64_t last_pat_ts;
>  int64_t last_sdt_ts;
> +int pcr_all_video;
> +int pcr_all_audio;
>
>  int omit_video_pes_length;
>  } MpegTSWrite;
> @@ -1178,11 +1180,18 @@ static void mpegts_write_pes(AVFormatContext *s,
> AVStream *st,
>  int64_t pcr = -1; /* avoid warning */
>  int64_t delay = av_rescale(s->max_delay, 9, AV_TIME_BASE);
>  int force_pat = st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && key
> && !ts_st->prev_payload_key;
> +int force_pcr = 0;
>
>  av_assert0(ts_st->payload != buf || st->codecpar->codec_type !=
> AVMEDIA_TYPE_VIDEO);
>  if (ts->flags & MPEGTS_FLAG_PAT_PMT_AT_FRAMES &&
> st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
>  force_pat = 1;
>  }
> +if (ts->pcr_all_video && st->codecpar->codec_type ==
> AVMEDIA_TYPE_VIDEO) {
> +force_pcr = 1;
> +}
> +if (ts->pcr_all_audio && st->codecpar->codec_type ==
> AVMEDIA_TYPE_AUDIO) {
> +force_pcr = 1;
> +}
>
>  is_start = 1;
>  while (payload_size > 0) {
> @@ -1190,7 +1199,7 @@ static void mpegts_write_pes(AVFormatContext *s,
> AVStream *st,
>  force_pat = 0;
>
>  write_pcr = 0;
> -if (ts_st->pid == ts_st->service->pcr_pid) {
> +if (ts_st->pid == ts_st->service->pcr_pid || force_pcr) {
>  if (ts->mux_rate > 1 || is_start) // VBR pcr period is based
> on frames
>  ts_st->service->pcr_packet_count++;
>  if (ts_st->service->pcr_packet_count >=
> @@ -1228,7 +1237,7 @@ static void mpegts_write_pes(AVFormatContext *s,
> AVStream *st,
>  }
>  if (key && is_start && pts != AV_NOPTS_VALUE) {
>  // set Random Access for key frames
> -if (ts_st->pid == ts_st->service->pcr_pid)
> +if (ts_st->pid == ts_st->service->pcr_pid || force_pcr)
>  write_pcr = 1;
>  set_af_flag(buf, 0x40);
>  q = get_ts_payload_start(buf);
> @@ -1951,6 +1960,12 @@ static const 

Re: [FFmpeg-devel] [PATCH] libavcodec/cuviddec A53CC closed captions support added to cuviddec & nvenc

2018-05-03 Thread Andrey Turkin
cuvid decoder has one advantage over nvdec: it has a hardware deinterlacer
support. BTW not sure if this patch takes that into account. So cuvid is
the only way to get GPU-deinterlaced frames until someone makes CUDA-based
deinterlace filter.

2018-05-03 12:03 GMT+03:00 Timo Rothenpieler :

> The nvenc side looks ok except for one or two minor nits which I will
> correct locally and push it with my next batch of patches.
>
> I'm not so sure on the cuvid side of things. A53 support is already
> provided via the new nvdec hwaccel, which supports it natively through the
> ffmpeg codec parsers.
> It doesn't seem right to add so much duplicated and involved parsing
> logic. If there was a way to use the a53 parser ffmpeg already has, it
> would probably be ok.
>
>
> ___
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
>
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


Re: [FFmpeg-devel] [PATCH] libavcodec/cuviddec A53CC closed captions support added to cuviddec & nvenc

2018-05-03 Thread Andrey Turkin
NVENC side of things should be ok now that drivers are fixed and SEI is
reordered together with frames, but on CUVID side it is still pretty bad. I
find it funny that NVIDIA developer submits someone's hackish patch instead
of fixing cuvid parser API and implementing this properly. I mean,
retrieving SEI data attached to pictures has to be a requested feature, not
just limited to A53.


2018-05-03 11:34 GMT+03:00 Roman Arzumanyan :

>
>
> --
> BR, Roman Arzumanyan
>
>
> 
> ---
> This email message is for the sole use of the intended recipient(s) and
> may contain
> confidential information.  Any unauthorized review, use, disclosure or
> distribution
> is prohibited.  If you are not the intended recipient, please contact the
> sender by
> reply email and destroy all copies of the original message.
> 
> ---
>
> ___
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
>
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


Re: [FFmpeg-devel] [PATCH] movtextenc: fix handling of utf-8 subtitles

2018-03-28 Thread Andrey Turkin
I think first check (ascii case) should be explicit bit-test, or (if there
is some reason to use sign-bit approach) at least "c" should be signed char
instead of simply char.

2018-03-28 6:07 GMT+03:00 Philip Langdale :

> See the earlier fix for movtextdec for details. The equivalent bug is
> present on the encoder side as well.
>
> We need to track the text length in 'characters' (which seems to really
> mean codepoints) to ensure that styles are applied across the correct
> ranges.
>
> Signed-off-by: Philip Langdale 
> ---
>  libavcodec/movtextenc.c | 24 +++-
>  1 file changed, 23 insertions(+), 1 deletion(-)
>
> diff --git a/libavcodec/movtextenc.c b/libavcodec/movtextenc.c
> index d795e317c3..fd0743f752 100644
> --- a/libavcodec/movtextenc.c
> +++ b/libavcodec/movtextenc.c
> @@ -304,11 +304,33 @@ static void mov_text_color_cb(void *priv, unsigned
> int color, unsigned int color
>   */
>  }
>
> +static uint16_t utf8_strlen(const char *text, int len)
> +{
> +uint16_t i = 0, ret = 0;
> +while (i < len) {
> +char c = text[i];
> +if (c >= 0)
> +i += 1;
> +else if ((c & 0xE0) == 0xC0)
> +i += 2;
> +else if ((c & 0xF0) == 0xE0)
> +i += 3;
> +else if ((c & 0xF8) == 0xF0)
> +i += 4;
> +else
> +return 0;
> +ret++;
> +}
> +return ret;
> +}
> +
>  static void mov_text_text_cb(void *priv, const char *text, int len)
>  {
> +uint16_t utf8_len = utf8_strlen(text, len);
>  MovTextContext *s = priv;
>  av_bprint_append_data(>buffer, text, len);
> -s->text_pos += len;
> +// If it's not utf-8, just use the byte length
> +s->text_pos += utf8_len ? utf8_len : len;
>  }
>
>  static void mov_text_new_line_cb(void *priv, int forced)
> --
> 2.14.1
>
> ___
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


Re: [FFmpeg-devel] Asynchronously delivering data to FFmpeg, and extending the API to do this...

2018-03-20 Thread Andrey Turkin
I've had a need for something similar a while back and the best solution I
could come up with was using stackful coroutines to invert code flow.
Basically the main program would fire up the the coroutine, the coroutine
would set up avformat context with custom AVIO (avio's read callback
transfers execution back to main program) and then it would go into a cycle
reading packets from avformat. Every time main program needs to process
more data, it would add it to avio's buffer and resume the coroutine;
coroutine would then return into avformat internals which would process it
as if nothing had happened. Basically main program goes into coroutine each
time it needs to process more data, and coroutine returns to main program
every time it needs more data or upon receiving AVPacket from avformat call.
I don't really like that solution as it is a bit fragile, requires some
quirks to work around some issues, hinders readability as well as
debuggability.
I'd really like to see something like new avcodec's API where one can push
data in and then get the processed data out (and avio as a separate
component which can be pulled from?). However that probably requires
(assuming ffmpeg stays in C) rewriting all of avformat into some kind of
state-machine monstrosity which nobody wants to do.

2018-03-20 11:43 GMT+03:00 Hendrik Leppkes :

> On Tue, Mar 20, 2018 at 3:06 AM, Philip Prindeville
>  wrote:
> >
> > What’s involved in doing this?
> >
>
> Re-writing every single demuxer in libavformat, probably.
>
> It seems entirely unfeasible to me to do this, because nothing in the
> architecture even remotely supports something like this. IO is
> fundamentally a "pull" model in ffmpeg, all components pull data as
> they need it, and they don't have any mechanism to give feedback when
> a packet was finished, or anything like that.
> If you have a push data source, the easiest way to interface with
> ffmpeg would be to buffer data and let it pull from the buffer as it
> needs (with blocking when waiting for new data, possibly). It'll tell
> you if it finished a frame because av_read_frame returns one to you.
>
> Obviously this defeats the purpose of using an event-based source, but
> if thats all you have, then you gotta make it work somehow.
>
> - Hendrik
> ___
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


Re: [FFmpeg-devel] [FFmpeg-cvslog] Merge commit '4fb311c804098d78e5ce5f527f9a9c37536d3a08'

2017-03-20 Thread Andrey Turkin
I'd like to use this opportunity to remind of
http://ffmpeg.org/pipermail/ffmpeg-devel/2017-February/207513.html


2017-03-20 14:29 GMT+03:00 Michael Niedermayer :

> On Mon, Mar 20, 2017 at 10:14:21AM +0100, Hendrik Leppkes wrote:
> > On Mon, Mar 20, 2017 at 10:11 AM, Carl Eugen Hoyos 
> wrote:
> > > 2017-03-20 10:03 GMT+01:00 Hendrik Leppkes :
> > >> On Mon, Mar 20, 2017 at 9:59 AM, Carl Eugen Hoyos 
> wrote:
> > >>> 2017-03-20 9:42 GMT+01:00 Clément Bœsch :
> >  On Mon, Mar 20, 2017 at 09:38:15AM +0100, Carl Eugen Hoyos wrote:
> > > 2017-03-20 9:35 GMT+01:00 Clément Bœsch :
> > > > On Mon, Mar 20, 2017 at 09:17:36AM +0100, Carl Eugen Hoyos wrote:
> > > >> 2017-03-20 8:57 GMT+01:00 Clément Bœsch :
> > > >> > ffmpeg | branch: master | Clément Bœsch  | Mon Mar
> 20 08:52:07 2017 +0100| [3835283293bfd38ba69203f4618f0f0f21377bcc] |
> committer: Clément Bœsch
> > > >> >
> > > >> > Merge commit '4fb311c804098d78e5ce5f527f9a9c37536d3a08'
> > > >> >
> > > >> > * commit '4fb311c804098d78e5ce5f527f9a9c37536d3a08':
> > > >> >   Drop memalign hack
> > > >> >
> > > >> > Merged, as this may indeed be uneeded since
> > > >> > 46e3936fb04d06550151e667357065e3f646da1a.
> > > >>
> > > >> How are we supposed to test the next crash because
> > > >> of missing alignment?
> > > >>
> > > >
> > > > I thought it was only about compatibility with platforms not
> having
> > > > an aligned allocator.
> > >
> > > If you think such platforms exist, one more reason not to merge...
> > 
> >  There was apparently MinGW but it seemed to have been fixed
> >  (see the hash reference in the merge description).
> > >>>
> > >>> I can only add that the simple idea of removing support for
> > >>> platforms without any cause fills me with shame.
> > >>>
> > >>
> > >> If you can name a platfom that needs this in current git master, then
> > >> we can move forward.
> > >
> > > Old MingW comes to mind...
> > >
> >
> > As was pointed out above, old mingw was fixed in another commit right
> > before this one.
> > If you can find an actual reproducable case on current git master,
> > please do provide said information.
>
> Is the mixture of memalign() and free() spec compliant ?
>
> IIRC you said in IRC memalign and free would be ok in posix but as i
> checked now i cannot find memalign in posix only posix_memalign()
> but maybe i looked at the wrong place
>
>
> [...]
> --
> Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB
>
> The worst form of inequality is to try to make unequal things equal.
> -- Aristotle
>
> ___
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
>
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


[FFmpeg-devel] [PATCH] Handle build environment where both posix_malloc and _aligned_alloc are available

2017-02-23 Thread Andrey Turkin
av_malloc prefers posix_malloc over _aligned_alloc so realloc and free 
functions must be used when posix_malloc is available. This fixes mingw32 
builds when using custom allocators.
---
 libavutil/mem.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libavutil/mem.c b/libavutil/mem.c
index 1a8fc21e98..d0065a09d5 100644
--- a/libavutil/mem.c
+++ b/libavutil/mem.c
@@ -162,7 +162,7 @@ void *av_realloc(void *ptr, size_t size)
 if (ptr)
 ptr = (char *)ptr + diff;
 return ptr;
-#elif HAVE_ALIGNED_MALLOC
+#elif HAVE_ALIGNED_MALLOC && !HAVE_POSIX_MEMALIGN
 return _aligned_realloc(ptr, size + !size, ALIGN);
 #else
 return realloc(ptr, size + !size);
@@ -233,7 +233,7 @@ void av_free(void *ptr)
 av_assert0(v>0 && v<=ALIGN);
 free((char *)ptr - v);
 }
-#elif HAVE_ALIGNED_MALLOC
+#elif HAVE_ALIGNED_MALLOC && !HAVE_POSIX_MEMALIGN
 _aligned_free(ptr);
 #else
 free(ptr);
-- 
2.11.0

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


Re: [FFmpeg-devel] [PATCH]lavf/mpegtsenc: Set min PID for data pkt to 0x0010

2016-09-26 Thread Andrey Turkin
Nevermind, I didn't though this through. Default value is high enough to
comply with all standards.  If someone really wants/needs to use 0x0010 as
PMT/data pids then it should be permitted since it is permitted by
13818-1:2000. By the same logic upper limit should be set to 0x1FFE. Though
it would be good if someone with an access to later versions of the
standard could verify if these limits are still the same.

2016-09-27 6:24 GMT+03:00 Andrey Turkin <andrey.tur...@gmail.com>:

> ISO 18318 reserves PIDs 0x00-0x0F
> DVB also reserves PIDs 0x10-0x1F
> ARIB also reserves PIDs 0x20-0x2F
> ATSC also reserves PID 0x1FFB
>
> So, if there is going to be change to permitted PIDs assignment anyway, I
> suggest to go with safest choice and use 0x0030-0x1FEF range
>
> 2016-09-27 4:41 GMT+03:00 Michael Niedermayer <mich...@niedermayer.cc>:
>
>> On Sat, Sep 24, 2016 at 12:06:07PM +0200, Carl Eugen Hoyos wrote:
>> > Hi!
>> >
>> > Attached patch fixes ticket #1673.
>> > ISO13818-1 indeed specifies in §2.4.3.3 that values
>> > up to 0xF are reserved.
>> >
>> > Please comment, Carl Eugen
>>
>> >  mpegtsenc.c |2 +-
>> >  1 file changed, 1 insertion(+), 1 deletion(-)
>> > 60a99310ff7b9ef476fa1d70bb01ffcaaf550226
>> 0001-lavf-mpegtsenc-Set-min-PID-for-data-pkt-to-0x0010.patch
>> > From 06371416c00eaf73430d1bb7d841167356adbe23 Mon Sep 17 00:00:00 2001
>> > From: Sylvain Laurent <syll...@gmail.com>
>> > Date: Sat, 24 Sep 2016 12:01:34 +0200
>> > Subject: [PATCH] lavf/mpegtsenc: Set min PID for data pkt to 0x0010.
>> >
>> > Fixes ticket #1673.
>> > ---
>> >  libavformat/mpegtsenc.c |2 +-
>> >  1 file changed, 1 insertion(+), 1 deletion(-)
>> >
>> > diff --git a/libavformat/mpegtsenc.c b/libavformat/mpegtsenc.c
>> > index fd849e5..c10a3bf 100644
>> > --- a/libavformat/mpegtsenc.c
>> > +++ b/libavformat/mpegtsenc.c
>> > @@ -1843,7 +1843,7 @@ static const AVOption options[] = {
>> >{ .i64 = 0x1000 }, 0x0010, 0x1f00, AV_OPT_FLAG_ENCODING_PARAM },
>> >  { "mpegts_start_pid", "Set the first pid.",
>> >offsetof(MpegTSWrite, start_pid), AV_OPT_TYPE_INT,
>> > -  { .i64 = 0x0100 }, 0x0020, 0x0f00, AV_OPT_FLAG_ENCODING_PARAM },
>> > +  { .i64 = 0x0100 }, 0x0010, 0x0f00, AV_OPT_FLAG_ENCODING_PARAM },
>> >  { "mpegts_m2ts_mode", "Enable m2ts mode.",
>>
>> the previous limit was set by Zach Swena (in CC)
>> was there a reason why it was 0x20 and not 0x10 ?
>>
>> Thanks
>>
>> [...]
>>
>>
>> --
>> Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB
>>
>> Never trust a computer, one day, it may think you are the virus. -- Compn
>>
>> ___
>> ffmpeg-devel mailing list
>> ffmpeg-devel@ffmpeg.org
>> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>>
>>
>
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


Re: [FFmpeg-devel] [PATCH]lavf/mpegtsenc: Set min PID for data pkt to 0x0010

2016-09-26 Thread Andrey Turkin
ISO 18318 reserves PIDs 0x00-0x0F
DVB also reserves PIDs 0x10-0x1F
ARIB also reserves PIDs 0x20-0x2F
ATSC also reserves PID 0x1FFB

So, if there is going to be change to permitted PIDs assignment anyway, I
suggest to go with safest choice and use 0x0030-0x1FEF range

2016-09-27 4:41 GMT+03:00 Michael Niedermayer :

> On Sat, Sep 24, 2016 at 12:06:07PM +0200, Carl Eugen Hoyos wrote:
> > Hi!
> >
> > Attached patch fixes ticket #1673.
> > ISO13818-1 indeed specifies in §2.4.3.3 that values
> > up to 0xF are reserved.
> >
> > Please comment, Carl Eugen
>
> >  mpegtsenc.c |2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> > 60a99310ff7b9ef476fa1d70bb01ffcaaf550226  0001-lavf-mpegtsenc-Set-min-
> PID-for-data-pkt-to-0x0010.patch
> > From 06371416c00eaf73430d1bb7d841167356adbe23 Mon Sep 17 00:00:00 2001
> > From: Sylvain Laurent 
> > Date: Sat, 24 Sep 2016 12:01:34 +0200
> > Subject: [PATCH] lavf/mpegtsenc: Set min PID for data pkt to 0x0010.
> >
> > Fixes ticket #1673.
> > ---
> >  libavformat/mpegtsenc.c |2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/libavformat/mpegtsenc.c b/libavformat/mpegtsenc.c
> > index fd849e5..c10a3bf 100644
> > --- a/libavformat/mpegtsenc.c
> > +++ b/libavformat/mpegtsenc.c
> > @@ -1843,7 +1843,7 @@ static const AVOption options[] = {
> >{ .i64 = 0x1000 }, 0x0010, 0x1f00, AV_OPT_FLAG_ENCODING_PARAM },
> >  { "mpegts_start_pid", "Set the first pid.",
> >offsetof(MpegTSWrite, start_pid), AV_OPT_TYPE_INT,
> > -  { .i64 = 0x0100 }, 0x0020, 0x0f00, AV_OPT_FLAG_ENCODING_PARAM },
> > +  { .i64 = 0x0100 }, 0x0010, 0x0f00, AV_OPT_FLAG_ENCODING_PARAM },
> >  { "mpegts_m2ts_mode", "Enable m2ts mode.",
>
> the previous limit was set by Zach Swena (in CC)
> was there a reason why it was 0x20 and not 0x10 ?
>
> Thanks
>
> [...]
>
>
> --
> Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB
>
> Never trust a computer, one day, it may think you are the virus. -- Compn
>
> ___
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
>
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


Re: [FFmpeg-devel] Discussion: How to extend the AVFrame to hold caption data?

2016-09-04 Thread Andrey Turkin
AVFrame already has some support for embedded 608/708 subtitles in a form
of side data (AV_FRAME_DATA_A53_CC tag), and some decoders/encoders already
can handle that.
Main issue with this approach is that video frames can be modified, removed
or duplicated (mainly by video filters but also by ffmpeg's video sync
code).

2016-09-04 6:14 GMT+03:00 Jonathan Campbell :

> While I'm finishing up the CNG patch, I'd like to start developing another
> feature that I think FFMPEG should be able to at least expose through the
> API.
>
> I'm aware that FFMPEG supports subtitle tracks, but as far as I know,
> doesn't support caption data embedded in the video stream itself.
>
> Some scenarios especially in broadcast TV transmit MPEG-2 or H.264 video
> with caption data embedded in the encoded frame. I would like to write a
> patch that can read the caption data embedded in MPEG-2 user packets and
> expose it in the AVFrame.
>
> There are two common forms I work with in software: One carries EIA 608
> closed caption packets per keyframe (typically seen on DVDs here in
> America), the other carries CEA 708 closed caption data (Caption
> Description Packets) every frame (or every I/P frame) with a side channel
> for 608 (typically seen in terrestrial HDTV broadcast here in America). How
> could I modify the MPEG-2 decoder and/or bitstream parser to read and
> expose this data through the API for software that needs it? I'm also
> interested in modding the MPEG-2 encoder to take this data through the API
> and encode it into the frame. If done right, the extension could allow
> FFMPEG to transcode DVD or HDTV broadcasts while keeping the caption data
> intact.
>
> Similar standards exist to carry caption data packets in H.264 (as SEI
> packets) and DV video (as DIF packets).
>
> Jonathan Campbell
> ___
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


Re: [FFmpeg-devel] [PATCH v2 1/2] avcodec/cuvid: add cuvid decoder

2016-06-06 Thread Andrey Turkin
2016-06-07 1:08 GMT+03:00 Timo Rothenpieler :

> +if (ctx->cudecoder) {
> +av_log(avctx, AV_LOG_ERROR, "re-initializing decoder is not
> supported\n");
> +ctx->internal_error = AVERROR(EINVAL);
> +return 0;
> +}
> +
> +if (hwframe_ctx->pool) {
> +av_log(avctx, AV_LOG_ERROR, "AVHWFramesContext is already
> initialized\n");
> +ctx->internal_error = AVERROR(EINVAL);
> +return 0;
> +}
>
Good enough for initial implementation but eventually should be revisited -
on-the-fly video parameter changes can occur in the wild.
Rest of ffmpeg might not be ready for changing hw_frames_ctx though.

+if (avpkt->size && filtered_packet.size) {
> +cupkt.payload_size = filtered_packet.size;
> +cupkt.payload = filtered_packet.data;
> +
> +if (filtered_packet.pts != AV_NOPTS_VALUE) {
> +cupkt.flags = CUVID_PKT_TIMESTAMP;
> +cupkt.timestamp = av_rescale_q(filtered_packet.pts,
> avctx->time_base, (AVRational){1, 1000});
> +}
> +} else {
> +cupkt.flags = CUVID_PKT_ENDOFSTREAM;
> +}
>
This works for this particular bsf but it is still a wrong logic.
filtered_packet has nothing to do with EOS signalling. If filtered_packet
is ever empty and avpkt isn't - that just means BSF didn't output anything
for that particular packet and there is nothing to do.
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


Re: [FFmpeg-devel] [PATCH 2/2] ffmpeg: Add cuvid hwaccel support

2016-06-06 Thread Andrey Turkin
2016-06-05 21:58 GMT+03:00 Timo Rothenpieler :


> +/* check if the decoder supports CUVID and the output only goes to
> this stream */
> +if (ist->nb_filters || ist->hwaccel_id != HWACCEL_CUVID || !ist->dec
> || !ist->dec->pix_fmts)
> +goto cancel;
> +for (pix_fmt = ist->dec->pix_fmts; *pix_fmt != AV_PIX_FMT_NONE;
> pix_fmt++)
> +if (*pix_fmt == AV_PIX_FMT_CUDA)
> +break;
> +if (*pix_fmt == AV_PIX_FMT_NONE)
> +goto cancel;
> +
> +for (i = 0; i < nb_output_streams; i++)
> +if (output_streams[i] != ost && output_streams[i]->source_index
> == ost->source_index)
> +goto cancel;
>

Is it possible to enhance this to support 1-to-N transcoding (usecase
solved by NVidia's patch with nvresize)? One can do the same with complex
filtergraph with several scale_npp instances. This seems like a bit of
over-restriction.

+err = cuInit(0);
> +if (err != CUDA_SUCCESS) {
> +av_log(NULL, AV_LOG_ERROR, "Could not initialize the CUDA driver
> API\n");
> +ret = AVERROR_UNKNOWN;
> +goto error;
> +}
> +
> +err = cuDeviceGet(, 0); ///TODO: Make device index configurable
> +if (err != CUDA_SUCCESS) {
> +av_log(NULL, AV_LOG_ERROR, "Could not get the device number
> %d\n", 0);
> +ret = AVERROR_UNKNOWN;
> +goto error;
> +}
> +
> +err = cuCtxCreate(_ctx, CU_CTX_SCHED_BLOCKING_SYNC, device);
> +if (err != CUDA_SUCCESS) {
> +av_log(NULL, AV_LOG_ERROR, "Error creating a CUDA context\n");
> +ret = AVERROR_UNKNOWN;
> +goto error;
> +}
> +
> +device_ctx = (AVHWDeviceContext*)hw_device_ctx->data;
> +device_ctx->free = cuvid_ctx_free;
> +
> +device_hwctx = device_ctx->hwctx;
> +device_hwctx->cuda_ctx = cuda_ctx;
> +
> +err = cuCtxPopCurrent();
> +if (err != CUDA_SUCCESS) {
> +av_log(NULL, AV_LOG_ERROR, "cuCtxPopCurrent failed\n");
> +ret = AVERROR_UNKNOWN;
> +goto error;
> +}
> +


It begs to merge in device_create functionality from libav
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


Re: [FFmpeg-devel] [PATCH 1/2] avcodec/cuvid: add cuvid decoder

2016-06-06 Thread Andrey Turkin
2016-06-05 21:58 GMT+03:00 Timo Rothenpieler :

> +
> +avctx->width = format->coded_width;
> +avctx->height = format->coded_height;
> +
>

This patch seems to mix bitstream picture dimensions and output picture
dimensions in several places. Can you test if the decoder works with input
video of "strange" size (say, 325x243)?

+hwframe_ctx->format = AV_PIX_FMT_CUDA;
> +hwframe_ctx->sw_format = AV_PIX_FMT_NV12;
> +hwframe_ctx->width = FFALIGN(cuinfo.ulTargetWidth, 16);
> +hwframe_ctx->height = FFALIGN(cuinfo.ulTargetHeight, 16);
>

NVENC aligns to 32 (I think hevc requires this sometimes); maybe use same
here?
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


[FFmpeg-devel] [PATCH 2/2] nvenc: add an option to embed A53 closed captions

2016-06-04 Thread Andrey Turkin

It mimics same options in libx264 and qsv_h264 encoders
---
 libavcodec/nvenc.c  | 28 ++--
 libavcodec/nvenc.h  |  1 +
 libavcodec/nvenc_h264.c |  1 +
 libavcodec/nvenc_hevc.c |  1 +
 4 files changed, 29 insertions(+), 2 deletions(-)

diff --git a/libavcodec/nvenc.c b/libavcodec/nvenc.c
index d3115f4..010819a 100644
--- a/libavcodec/nvenc.c
+++ b/libavcodec/nvenc.c
@@ -1374,7 +1374,8 @@ static int nvenc_upload_frame(AVCodecContext *avctx, const AVFrame *frame,
 }
 
 static void nvenc_codec_specific_pic_params(AVCodecContext *avctx,
-NV_ENC_PIC_PARAMS *params)
+NV_ENC_PIC_PARAMS *params,
+NV_ENC_SEI_PAYLOAD *sei_data)
 {
 NvencContext *ctx = avctx->priv_data;
 
@@ -1384,12 +1385,20 @@ static void nvenc_codec_specific_pic_params(AVCodecContext *avctx,
 ctx->encode_config.encodeCodecConfig.h264Config.sliceMode;
 params->codecPicParams.h264PicParams.sliceModeData =
 ctx->encode_config.encodeCodecConfig.h264Config.sliceModeData;
+if (sei_data) {
+ params->codecPicParams.h264PicParams.seiPayloadArray = sei_data;
+ params->codecPicParams.h264PicParams.seiPayloadArrayCnt = 1;
+}
   break;
 case AV_CODEC_ID_HEVC:
 params->codecPicParams.hevcPicParams.sliceMode =
 ctx->encode_config.encodeCodecConfig.hevcConfig.sliceMode;
 params->codecPicParams.hevcPicParams.sliceModeData =
 ctx->encode_config.encodeCodecConfig.hevcConfig.sliceModeData;
+if (sei_data) {
+ params->codecPicParams.hevcPicParams.seiPayloadArray = sei_data;
+ params->codecPicParams.hevcPicParams.seiPayloadArrayCnt = 1;
+}
 break;
 }
 }
@@ -1576,6 +1585,8 @@ int ff_nvenc_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
 {
 NVENCSTATUS nv_status;
 NvencSurface *tmpoutsurf, *inSurf;
+NV_ENC_SEI_PAYLOAD *sei_data = NULL;
+size_t sei_size;
 int res;
 
 NvencContext *ctx = avctx->priv_data;
@@ -1616,12 +1627,25 @@ int ff_nvenc_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
 pic_params.encodePicFlags = 0;
 pic_params.inputTimeStamp = frame->pts;
 
-nvenc_codec_specific_pic_params(avctx, _params);
+if (ctx->a53_cc) {
+if (ff_alloc_a53_sei(frame, sizeof(NV_ENC_SEI_PAYLOAD), (void**)_data, _size) < 0) {
+av_log(ctx, AV_LOG_ERROR, "Not enough memory for closed captions, skipping\n");
+}
+
+if (sei_data) {
+sei_data->payloadSize = (uint32_t)sei_size;
+sei_data->payloadType = 4;
+sei_data->payload = (uint8_t*)(sei_data + 1);
+}
+}
+
+nvenc_codec_specific_pic_params(avctx, _params, sei_data);
 } else {
 pic_params.encodePicFlags = NV_ENC_PIC_FLAG_EOS;
 }
 
 nv_status = p_nvenc->nvEncEncodePicture(ctx->nvencoder, _params);
+av_free(sei_data);
 if (nv_status != NV_ENC_SUCCESS &&
 nv_status != NV_ENC_ERR_NEED_MORE_INPUT)
 return nvenc_print_error(avctx, nv_status, "EncodePicture failed!");
diff --git a/libavcodec/nvenc.h b/libavcodec/nvenc.h
index 961cbc7..71f538a 100644
--- a/libavcodec/nvenc.h
+++ b/libavcodec/nvenc.h
@@ -174,6 +174,7 @@ typedef struct NvencContext
 int device;
 int flags;
 int async_depth;
+int a53_cc;
 } NvencContext;
 
 int ff_nvenc_encode_init(AVCodecContext *avctx);
diff --git a/libavcodec/nvenc_h264.c b/libavcodec/nvenc_h264.c
index cdb80f2..eb9cb31 100644
--- a/libavcodec/nvenc_h264.c
+++ b/libavcodec/nvenc_h264.c
@@ -83,6 +83,7 @@ static const AVOption options[] = {
 { "any",  "Pick the first device available",  0,   AV_OPT_TYPE_CONST,  { .i64 = ANY_DEVICE },   0, 0, VE, "gpu" },
 { "list", "List the available devices",   0,   AV_OPT_TYPE_CONST,  { .i64 = LIST_DEVICES }, 0, 0, VE, "gpu" },
 { "delay","Delay frame output by the given amount of frames", OFFSET(async_depth), AV_OPT_TYPE_INT, { .i64 = INT_MAX }, 0, INT_MAX, VE },
+{ "a53cc","Use A53 Closed Captions (if available)", OFFSET(a53_cc),AV_OPT_TYPE_BOOL,   { .i64 = 1 },0, 1, VE},
 { NULL }
 };
 
diff --git a/libavcodec/nvenc_hevc.c b/libavcodec/nvenc_hevc.c
index cef19f7..5458eef 100644
--- a/libavcodec/nvenc_hevc.c
+++ b/libavcodec/nvenc_hevc.c
@@ -80,6 +80,7 @@ static const AVOption options[] = {
 { "any",  "Pick the first device available",  0,   AV_OPT_TYPE_CONST,  { .i64 = ANY_DEVICE },   0, 0, VE, "device" },
 { "list", "List the available devices",   0,   AV_OPT_TYPE_CONST,  { .i64 = LIST_DEVICES }, 0, 0, VE, "device" },
 { "delay","Delay frame output by the given amount of frames", 

[FFmpeg-devel] [PATCH 1/2] libavcodec: factor out SEI generation for A53 captions

2016-06-04 Thread Andrey Turkin
---
 libavcodec/internal.h| 15 +
 libavcodec/libx264.c | 49 ++---
 libavcodec/qsvenc.c  |  4 +--
 libavcodec/qsvenc_h264.c | 82 +++-
 libavcodec/utils.c   | 43 +
 5 files changed, 101 insertions(+), 92 deletions(-)

diff --git a/libavcodec/internal.h b/libavcodec/internal.h
index be54471..000fe26 100644
--- a/libavcodec/internal.h
+++ b/libavcodec/internal.h
@@ -345,4 +345,19 @@ AVCPBProperties *ff_add_cpb_side_data(AVCodecContext *avctx);
 
 int ff_side_data_set_encoder_stats(AVPacket *pkt, int quality, int64_t *error, int error_count, int pict_type);
 
+/**
+ * Check AVFrame for A53 side data and allocate and fill SEI message with A53 info
+ *
+ * @param frame  Raw frame to get A53 side data from
+ * @param prefix_len Number of bytes to allocate before SEI message
+ * @param data   Pointer to a variable to store allocated memory
+ *   Upon return the variable will hold NULL on error or if frame has no A53 info.
+ *   Otherwise it will point to prefix_len uninitialized bytes followed by
+ *   *sei_size SEI message
+ * @param sei_size   Pointer to a variable to store generated SEI message length
+ * @return   Zero on success, negative error code on failure
+ */
+int ff_alloc_a53_sei(const AVFrame *frame, size_t prefix_len,
+ void **data, size_t *sei_size);
+
 #endif /* AVCODEC_INTERNAL_H */
diff --git a/libavcodec/libx264.c b/libavcodec/libx264.c
index 449d76d..0063ae0 100644
--- a/libavcodec/libx264.c
+++ b/libavcodec/libx264.c
@@ -310,46 +310,29 @@ static int X264_frame(AVCodecContext *ctx, AVPacket *pkt, const AVFrame *frame,
 reconfig_encoder(ctx, frame);
 
 if (x4->a53_cc) {
-side_data = av_frame_get_side_data(frame, AV_FRAME_DATA_A53_CC);
-if (side_data) {
+void *sei_data;
+size_t sei_size;
+
+ret = ff_alloc_a53_sei(frame, 0, _data, _size);
+if (ret < 0) {
+av_log(ctx, AV_LOG_ERROR, "Not enough memory for closed captions, skipping\n");
+} else if (sei_data) {
 x4->pic.extra_sei.payloads = av_mallocz(sizeof(x4->pic.extra_sei.payloads[0]));
 if (x4->pic.extra_sei.payloads == NULL) {
 av_log(ctx, AV_LOG_ERROR, "Not enough memory for closed captions, skipping\n");
-goto skip_a53cc;
+av_free(sei_data);
+} else {
+x4->pic.extra_sei.sei_free = av_free;
+
+x4->pic.extra_sei.payloads[0].payload_size = sei_size;
+x4->pic.extra_sei.payloads[0].payload = sei_data;
+x4->pic.extra_sei.num_payloads = 1;
+x4->pic.extra_sei.payloads[0].payload_type = 4;
 }
-x4->pic.extra_sei.sei_free = av_free;
-
-x4->pic.extra_sei.payloads[0].payload_size = side_data->size + 11;
-x4->pic.extra_sei.payloads[0].payload = av_mallocz(x4->pic.extra_sei.payloads[0].payload_size);
-if (x4->pic.extra_sei.payloads[0].payload == NULL) {
-av_log(ctx, AV_LOG_ERROR, "Not enough memory for closed captions, skipping\n");
-av_freep(>pic.extra_sei.payloads);
-goto skip_a53cc;
-}
-x4->pic.extra_sei.num_payloads = 1;
-x4->pic.extra_sei.payloads[0].payload_type = 4;
-memcpy(x4->pic.extra_sei.payloads[0].payload + 10, side_data->data, side_data->size);
-x4->pic.extra_sei.payloads[0].payload[0] = 181;
-x4->pic.extra_sei.payloads[0].payload[1] = 0;
-x4->pic.extra_sei.payloads[0].payload[2] = 49;
-
-/**
- * 'GA94' is standard in North America for ATSC, but hard coding
- * this style may not be the right thing to do -- other formats
- * do exist. This information is not available in the side_data
- * so we are going with this right now.
- */
-AV_WL32(x4->pic.extra_sei.payloads[0].payload + 3,
-MKTAG('G', 'A', '9', '4'));
-x4->pic.extra_sei.payloads[0].payload[7] = 3;
-x4->pic.extra_sei.payloads[0].payload[8] =
-((side_data->size/3) & 0x1f) | 0x40;
-x4->pic.extra_sei.payloads[0].payload[9] = 0;
-x4->pic.extra_sei.payloads[0].payload[side_data->size+10] = 255;
 }
 }
 }
-skip_a53cc:
+
 do {
 if (x264_encoder_encode(x4->enc, , , frame? >pic: NULL, _out) < 0)
 return AVERROR_EXTERNAL;
diff --git a/libavcodec/qsvenc.c b/libavcodec/qsvenc.c
index 132cf47..f56cb61 100644
--- a/libavcodec/qsvenc.c
+++ b/libavcodec/qsvenc.c
@@ -781,9 +781,7 @@ 

[FFmpeg-devel] [PATCH] nvenc: add an option to embed A53 closed captions

2016-06-04 Thread Andrey Turkin

It mimics same options in libx264 and qsv_h264 encoders
---
 libavcodec/internal.h| 15 +
 libavcodec/libx264.c | 49 ++---
 libavcodec/nvenc.c   | 28 +++--
 libavcodec/nvenc.h   |  1 +
 libavcodec/nvenc_h264.c  |  1 +
 libavcodec/nvenc_hevc.c  |  1 +
 libavcodec/qsvenc.c  |  4 +--
 libavcodec/qsvenc_h264.c | 82 +++-
 libavcodec/utils.c   | 44 ++
 9 files changed, 131 insertions(+), 94 deletions(-)

diff --git a/libavcodec/internal.h b/libavcodec/internal.h
index be54471..000fe26 100644
--- a/libavcodec/internal.h
+++ b/libavcodec/internal.h
@@ -345,4 +345,19 @@ AVCPBProperties *ff_add_cpb_side_data(AVCodecContext *avctx);
 
 int ff_side_data_set_encoder_stats(AVPacket *pkt, int quality, int64_t *error, int error_count, int pict_type);
 
+/**
+ * Check AVFrame for A53 side data and allocate and fill SEI message with A53 info
+ *
+ * @param frame  Raw frame to get A53 side data from
+ * @param prefix_len Number of bytes to allocate before SEI message
+ * @param data   Pointer to a variable to store allocated memory
+ *   Upon return the variable will hold NULL on error or if frame has no A53 info.
+ *   Otherwise it will point to prefix_len uninitialized bytes followed by
+ *   *sei_size SEI message
+ * @param sei_size   Pointer to a variable to store generated SEI message length
+ * @return   Zero on success, negative error code on failure
+ */
+int ff_alloc_a53_sei(const AVFrame *frame, size_t prefix_len,
+ void **data, size_t *sei_size);
+
 #endif /* AVCODEC_INTERNAL_H */
diff --git a/libavcodec/libx264.c b/libavcodec/libx264.c
index 449d76d..0063ae0 100644
--- a/libavcodec/libx264.c
+++ b/libavcodec/libx264.c
@@ -310,46 +310,29 @@ static int X264_frame(AVCodecContext *ctx, AVPacket *pkt, const AVFrame *frame,
 reconfig_encoder(ctx, frame);
 
 if (x4->a53_cc) {
-side_data = av_frame_get_side_data(frame, AV_FRAME_DATA_A53_CC);
-if (side_data) {
+void *sei_data;
+size_t sei_size;
+
+ret = ff_alloc_a53_sei(frame, 0, _data, _size);
+if (ret < 0) {
+av_log(ctx, AV_LOG_ERROR, "Not enough memory for closed captions, skipping\n");
+} else if (sei_data) {
 x4->pic.extra_sei.payloads = av_mallocz(sizeof(x4->pic.extra_sei.payloads[0]));
 if (x4->pic.extra_sei.payloads == NULL) {
 av_log(ctx, AV_LOG_ERROR, "Not enough memory for closed captions, skipping\n");
-goto skip_a53cc;
+av_free(sei_data);
+} else {
+x4->pic.extra_sei.sei_free = av_free;
+
+x4->pic.extra_sei.payloads[0].payload_size = sei_size;
+x4->pic.extra_sei.payloads[0].payload = sei_data;
+x4->pic.extra_sei.num_payloads = 1;
+x4->pic.extra_sei.payloads[0].payload_type = 4;
 }
-x4->pic.extra_sei.sei_free = av_free;
-
-x4->pic.extra_sei.payloads[0].payload_size = side_data->size + 11;
-x4->pic.extra_sei.payloads[0].payload = av_mallocz(x4->pic.extra_sei.payloads[0].payload_size);
-if (x4->pic.extra_sei.payloads[0].payload == NULL) {
-av_log(ctx, AV_LOG_ERROR, "Not enough memory for closed captions, skipping\n");
-av_freep(>pic.extra_sei.payloads);
-goto skip_a53cc;
-}
-x4->pic.extra_sei.num_payloads = 1;
-x4->pic.extra_sei.payloads[0].payload_type = 4;
-memcpy(x4->pic.extra_sei.payloads[0].payload + 10, side_data->data, side_data->size);
-x4->pic.extra_sei.payloads[0].payload[0] = 181;
-x4->pic.extra_sei.payloads[0].payload[1] = 0;
-x4->pic.extra_sei.payloads[0].payload[2] = 49;
-
-/**
- * 'GA94' is standard in North America for ATSC, but hard coding
- * this style may not be the right thing to do -- other formats
- * do exist. This information is not available in the side_data
- * so we are going with this right now.
- */
-AV_WL32(x4->pic.extra_sei.payloads[0].payload + 3,
-MKTAG('G', 'A', '9', '4'));
-x4->pic.extra_sei.payloads[0].payload[7] = 3;
-x4->pic.extra_sei.payloads[0].payload[8] =
-((side_data->size/3) & 0x1f) | 0x40;
-x4->pic.extra_sei.payloads[0].payload[9] = 0;
-x4->pic.extra_sei.payloads[0].payload[side_data->size+10] = 255;
 }
 }
 }
-skip_a53cc:
+
 do {
 if (x264_encoder_encode(x4->enc, , , frame? >pic: NULL, 

[FFmpeg-devel] [PATCH] Load CUDA driver API dynamically when needed

2016-05-26 Thread Andrey Turkin
"libavutil/hwcontext_cuda.h"
+#include "libavutil/cuda_api.h"
 #include "libavutil/log.h"
 #include "libavutil/opt.h"
 
@@ -29,6 +30,7 @@
 
 typedef struct CudaUploadContext {
 const AVClass *class;
+AVCudaFunctions *api;
 int device_idx;
 
 AVBufferRef *hwdevice;
@@ -38,7 +40,8 @@ typedef struct CudaUploadContext {
 static void cudaupload_ctx_free(AVHWDeviceContext *ctx)
 {
 AVCUDADeviceContext *hwctx = ctx->hwctx;
-cuCtxDestroy(hwctx->cuda_ctx);
+AVCudaFunctions *api = ctx->user_opaque;
+api->cuCtxDestroy(hwctx->cuda_ctx);
 }
 
 static av_cold int cudaupload_init(AVFilterContext *ctx)
@@ -52,34 +55,41 @@ static av_cold int cudaupload_init(AVFilterContext *ctx)
 CUresult err;
 int ret;
 
-err = cuInit(0);
+s->api = avpriv_load_cuda();
+if (!s->api) {
+av_log(ctx, AV_LOG_ERROR, "Could not load the CUDA driver API\n");
+return AVERROR_UNKNOWN;
+}
+
+err = s->api->cuInit(0);
 if (err != CUDA_SUCCESS) {
 av_log(ctx, AV_LOG_ERROR, "Could not initialize the CUDA driver API\n");
 return AVERROR_UNKNOWN;
 }
 
-err = cuDeviceGet(, s->device_idx);
+err = s->api->cuDeviceGet(, s->device_idx);
 if (err != CUDA_SUCCESS) {
 av_log(ctx, AV_LOG_ERROR, "Could not get the device number %d\n", s->device_idx);
 return AVERROR_UNKNOWN;
 }
 
-err = cuCtxCreate(_ctx, 0, device);
+err = s->api->cuCtxCreate(_ctx, 0, device);
 if (err != CUDA_SUCCESS) {
 av_log(ctx, AV_LOG_ERROR, "Error creating a CUDA context\n");
 return AVERROR_UNKNOWN;
 }
 
-cuCtxPopCurrent();
+s->api->cuCtxPopCurrent();
 
 s->hwdevice = av_hwdevice_ctx_alloc(AV_HWDEVICE_TYPE_CUDA);
 if (!s->hwdevice) {
-cuCtxDestroy(cuda_ctx);
+s->api->cuCtxDestroy(cuda_ctx);
 return AVERROR(ENOMEM);
 }
 
 device_ctx   = (AVHWDeviceContext*)s->hwdevice->data;
 device_ctx->free = cudaupload_ctx_free;
+device_ctx->user_opaque = (void*)s->api;
 
 device_hwctx = device_ctx->hwctx;
 device_hwctx->cuda_ctx = cuda_ctx;
diff --git a/libavfilter/vf_scale_npp.c b/libavfilter/vf_scale_npp.c
index 68cee39..d9a9d86 100644
--- a/libavfilter/vf_scale_npp.c
+++ b/libavfilter/vf_scale_npp.c
@@ -30,6 +30,7 @@
 #include "libavutil/eval.h"
 #include "libavutil/hwcontext.h"
 #include "libavutil/hwcontext_cuda.h"
+#include "libavutil/cuda_api.h"
 #include "libavutil/internal.h"
 #include "libavutil/mathematics.h"
 #include "libavutil/opt.h"
@@ -100,6 +101,7 @@ typedef struct NPPScaleStageContext {
 typedef struct NPPScaleContext {
 const AVClass *class;
 
+AVCudaFunctions *api;
 NPPScaleStageContext stages[STAGE_NB];
 AVFrame *tmp_frame;
 int passthrough;
@@ -130,6 +132,12 @@ static int nppscale_init(AVFilterContext *ctx)
 NPPScaleContext *s = ctx->priv;
 int i;
 
+s->api = avpriv_load_cuda();
+if (!s->api) {
+av_log(ctx, AV_LOG_FATAL, "CUDA API is not available\n");
+return AVERROR(ENOSYS);
+}
+
 if (!strcmp(s->format_str, "same")) {
 s->format = AV_PIX_FMT_NONE;
 } else {
@@ -579,7 +587,7 @@ static int nppscale_filter_frame(AVFilterLink *link, AVFrame *in)
   (int64_t)in->sample_aspect_ratio.den * outlink->w * link->h,
   INT_MAX);
 
-err = cuCtxPushCurrent(device_hwctx->cuda_ctx);
+err = s->api->cuCtxPushCurrent(device_hwctx->cuda_ctx);
 if (err != CUDA_SUCCESS) {
 ret = AVERROR_UNKNOWN;
 goto fail;
@@ -587,7 +595,7 @@ static int nppscale_filter_frame(AVFilterLink *link, AVFrame *in)
 
 ret = nppscale_scale(ctx, out, in);
 
-cuCtxPopCurrent();
+s->api->cuCtxPopCurrent();
 if (ret < 0)
 goto fail;
 
diff --git a/libavutil/Makefile b/libavutil/Makefile
index a35deb6..469e074 100644
--- a/libavutil/Makefile
+++ b/libavutil/Makefile
@@ -151,7 +151,7 @@ OBJS = adler32.o\
 
 OBJS-$(!HAVE_ATOMICS_NATIVE)+= atomic.o \
 
-OBJS-$(CONFIG_CUDA) += hwcontext_cuda.o
+OBJS-$(CONFIG_CUDA) += hwcontext_cuda.o cuda_api.o
 OBJS-$(CONFIG_LZO)  += lzo.o
 OBJS-$(CONFIG_OPENCL)   += opencl.o opencl_internal.o
 OBJS-$(CONFIG_VAAPI)+= hwcontext_vaapi.o
@@ -162,7 +162,7 @@ OBJS += $(COMPAT_OBJS:%=../compat/%)
 # Windows resource file
 SLIBOBJS-$(HAVE_GNU_WINDRES)+= avutilres.o
 
-SKIPHEADERS-$(CONFIG_CUDA) += hwcontext_cuda.h
+SKIPHEADERS-$(CONFIG_CUDA) += hwcontext_cuda.h cuda_api.h
 SKIPHEADERS-$(CONFIG_VAAPI)+= hwcont

Re: [FFmpeg-devel] [PATCH] [v2] libavcodec/options.c: handle hw_frames_ctx where necessary

2016-05-22 Thread Andrey Turkin
Yeah, I saw that patch series today. Still should be fixed until the
function goes away. I'll send patch to libav as well shortly.

2016-05-22 16:39 GMT+03:00 Mark Thompson :

> Looks fine; it does fix an immediate problem.
>
> Note that development around hwcontext is mainly happening in libav, and
> this sort of copy support is not really an intended use.
>
> 
>
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


[FFmpeg-devel] [PATCH 4/4] libavcodec/nvenc.c: CUDA frames support

2016-05-20 Thread Andrey Turkin
---
 libavcodec/nvenc.c | 308 +++--
 1 file changed, 251 insertions(+), 57 deletions(-)

diff --git a/libavcodec/nvenc.c b/libavcodec/nvenc.c
index d3856a4..cad554c 100644
--- a/libavcodec/nvenc.c
+++ b/libavcodec/nvenc.c
@@ -33,16 +33,31 @@
 #include "libavutil/avassert.h"
 #include "libavutil/opt.h"
 #include "libavutil/mem.h"
+#include "libavutil/hwcontext.h"
 #include "avcodec.h"
 #include "internal.h"
 #include "thread.h"
 
+
+#if CONFIG_CUDA
+#include 
+#include "libavutil/hwcontext_cuda.h"
+#else
+
 #if defined(_WIN32)
 #define CUDAAPI __stdcall
 #else
 #define CUDAAPI
 #endif
 
+typedef enum cudaError_enum {
+CUDA_SUCCESS = 0
+} CUresult;
+typedef int CUdevice;
+typedef void* CUcontext;
+typedef void* CUdeviceptr;
+#endif
+
 #if defined(_WIN32)
 #define LOAD_FUNC(l, s) GetProcAddress(l, s)
 #define DL_CLOSE_FUNC(l) FreeLibrary(l)
@@ -51,12 +66,6 @@
 #define DL_CLOSE_FUNC(l) dlclose(l)
 #endif
 
-typedef enum cudaError_enum {
-CUDA_SUCCESS = 0
-} CUresult;
-typedef int CUdevice;
-typedef void* CUcontext;
-
 typedef CUresult(CUDAAPI *PCUINIT)(unsigned int Flags);
 typedef CUresult(CUDAAPI *PCUDEVICEGETCOUNT)(int *count);
 typedef CUresult(CUDAAPI *PCUDEVICEGET)(CUdevice *device, int ordinal);
@@ -68,9 +77,13 @@ typedef CUresult(CUDAAPI *PCUCTXDESTROY)(CUcontext ctx);
 
 typedef NVENCSTATUS (NVENCAPI* PNVENCODEAPICREATEINSTANCE)(NV_ENCODE_API_FUNCTION_LIST *functionList);
 
+#define MAX_REGISTERED_FRAMES 64
 typedef struct NvencSurface
 {
 NV_ENC_INPUT_PTR input_surface;
+AVFrame *in_ref;
+NV_ENC_MAP_INPUT_RESOURCE in_map;
+int reg_idx;
 int width;
 int height;
 
@@ -105,11 +118,16 @@ typedef struct NvencDynLoadFunctions
 int nvenc_device_count;
 CUdevice nvenc_devices[16];
 
+#if !CONFIG_CUDA
 #if defined(_WIN32)
 HMODULE cuda_lib;
-HMODULE nvenc_lib;
 #else
 void* cuda_lib;
+#endif
+#endif
+#if defined(_WIN32)
+HMODULE nvenc_lib;
+#else
 void* nvenc_lib;
 #endif
 } NvencDynLoadFunctions;
@@ -129,6 +147,7 @@ typedef struct NvencContext
 NV_ENC_INITIALIZE_PARAMS init_encode_params;
 NV_ENC_CONFIG encode_config;
 CUcontext cu_context;
+CUcontext cu_context_internal;
 
 int max_surface_count;
 NvencSurface *surfaces;
@@ -138,6 +157,17 @@ typedef struct NvencContext
 AVFifoBuffer *timestamp_list;
 int64_t last_dts;
 
+struct {
+CUdeviceptr ptr;
+NV_ENC_REGISTERED_PTR regptr;
+int mapped;
+} registered_frames[MAX_REGISTERED_FRAMES];
+int nb_registered_frames;
+
+/* the actual data pixel format, different from
+ * AVCodecContext.pix_fmt when using hwaccel frames on input */
+enum AVPixelFormat data_pix_fmt;
+
 void *nvencoder;
 
 char *preset;
@@ -299,6 +329,18 @@ static av_cold int nvenc_dyload_cuda(AVCodecContext *avctx)
 NvencContext *ctx = avctx->priv_data;
 NvencDynLoadFunctions *dl_fn = >nvenc_dload_funcs;
 
+#if CONFIG_CUDA
+dl_fn->cu_init  = cuInit;
+dl_fn->cu_device_get_count  = cuDeviceGetCount;
+dl_fn->cu_device_get= cuDeviceGet;
+dl_fn->cu_device_get_name   = cuDeviceGetName;
+dl_fn->cu_device_compute_capability = cuDeviceComputeCapability;
+dl_fn->cu_ctx_create= cuCtxCreate_v2;
+dl_fn->cu_ctx_pop_current   = cuCtxPopCurrent_v2;
+dl_fn->cu_ctx_destroy   = cuCtxDestroy_v2;
+
+return 1;
+#else
 if (dl_fn->cuda_lib)
 return 1;
 
@@ -332,6 +374,7 @@ error:
 dl_fn->cuda_lib = NULL;
 
 return 0;
+#endif
 }
 
 static av_cold int check_cuda_errors(AVCodecContext *avctx, CUresult err, const char *func)
@@ -357,7 +400,7 @@ static av_cold int nvenc_check_cuda(AVCodecContext *avctx)
 
 switch (avctx->codec->id) {
 case AV_CODEC_ID_H264:
-target_smver = avctx->pix_fmt == AV_PIX_FMT_YUV444P ? 0x52 : 0x30;
+target_smver = ctx->data_pix_fmt == AV_PIX_FMT_YUV444P ? 0x52 : 0x30;
 break;
 case AV_CODEC_ID_H265:
 target_smver = 0x52;
@@ -481,8 +524,10 @@ static av_cold void nvenc_unload_nvenc(AVCodecContext *avctx)
 
 dl_fn->nvenc_device_count = 0;
 
+#if !CONFIG_CUDA
 DL_CLOSE_FUNC(dl_fn->cuda_lib);
 dl_fn->cuda_lib = NULL;
+#endif
 
 dl_fn->cu_init = NULL;
 dl_fn->cu_device_get_count = NULL;
@@ -504,13 +549,33 @@ static av_cold int nvenc_setup_device(AVCodecContext *avctx)
 CUresult cu_res;
 CUcontext cu_context_curr;
 
+ctx->data_pix_fmt = avctx->pix_fmt;
+
+#if CONFIG_CUDA
+if (avctx->pix_fmt == AV_PIX_FMT_CUDA) {
+AVHWFramesContext *frames_ctx;
+AVCUDADeviceContext *device_hwctx;
+
+if (!avctx->hw_frames_ctx) {
+av_log(avctx, AV_LOG_ERROR, "hw_frames_ctx must be set when using GPU frames as input\n");
+return AVERROR(EINVAL);
+}
+
+frames_ctx = (AVHWFramesContext*)avctx->hw_frames_ctx->data;
+device_hwctx = 

[FFmpeg-devel] [PATCH 2/4] libavcodec/nvenc.c: combine input and output surface structures

2016-05-20 Thread Andrey Turkin

There is no point in separate structures as they have 1:1 relationship,
they are always used together and they have same lifetime.
---
 libavcodec/nvenc.c | 196 -
 1 file changed, 105 insertions(+), 91 deletions(-)

diff --git a/libavcodec/nvenc.c b/libavcodec/nvenc.c
index 3d53a0f..19312dc 100644
--- a/libavcodec/nvenc.c
+++ b/libavcodec/nvenc.c
@@ -67,7 +67,7 @@ typedef CUresult(CUDAAPI *PCUCTXDESTROY)(CUcontext ctx);
 
 typedef NVENCSTATUS (NVENCAPI* PNVENCODEAPICREATEINSTANCE)(NV_ENCODE_API_FUNCTION_LIST *functionList);
 
-typedef struct NvencInputSurface
+typedef struct NvencSurface
 {
 NV_ENC_INPUT_PTR input_surface;
 int width;
@@ -76,23 +76,16 @@ typedef struct NvencInputSurface
 int lockCount;
 
 NV_ENC_BUFFER_FORMAT format;
-} NvencInputSurface;
 
-typedef struct NvencOutputSurface
-{
 NV_ENC_OUTPUT_PTR output_surface;
 int size;
-
-NvencInputSurface* input_surface;
-
-int busy;
-} NvencOutputSurface;
+} NvencSurface;
 
 typedef struct NvencData
 {
 union {
 int64_t timestamp;
-NvencOutputSurface *surface;
+NvencSurface *surface;
 } u;
 } NvencData;
 
@@ -146,8 +139,7 @@ typedef struct NvencContext
 CUcontext cu_context;
 
 int max_surface_count;
-NvencInputSurface *input_surfaces;
-NvencOutputSurface *output_surfaces;
+NvencSurface *surfaces;
 
 NvencDataList output_surface_queue;
 NvencDataList output_surface_ready_queue;
@@ -217,6 +209,64 @@ static const NvencValuePair nvenc_hevc_level_pairs[] = {
 { NULL }
 };
 
+static const struct {
+NVENCSTATUS nverr;
+int averr;
+const char *desc;
+} nvenc_errors[] = {
+{ NV_ENC_SUCCESS,  0,"success"  },
+{ NV_ENC_ERR_NO_ENCODE_DEVICE, AVERROR(ENOENT),  "no encode device" },
+{ NV_ENC_ERR_UNSUPPORTED_DEVICE,   AVERROR(ENOSYS),  "unsupported device"   },
+{ NV_ENC_ERR_INVALID_ENCODERDEVICE,AVERROR(EINVAL),  "invalid encoder device"   },
+{ NV_ENC_ERR_INVALID_DEVICE,   AVERROR(EINVAL),  "invalid device"   },
+{ NV_ENC_ERR_DEVICE_NOT_EXIST, AVERROR(EIO), "device does not exist"},
+{ NV_ENC_ERR_INVALID_PTR,  AVERROR(EFAULT),  "invalid ptr"  },
+{ NV_ENC_ERR_INVALID_EVENT,AVERROR(EINVAL),  "invalid event"},
+{ NV_ENC_ERR_INVALID_PARAM,AVERROR(EINVAL),  "invalid param"},
+{ NV_ENC_ERR_INVALID_CALL, AVERROR(EINVAL),  "invalid call" },
+{ NV_ENC_ERR_OUT_OF_MEMORY,AVERROR(ENOMEM),  "out of memory"},
+{ NV_ENC_ERR_ENCODER_NOT_INITIALIZED,  AVERROR(EINVAL),  "encoder not initialized"  },
+{ NV_ENC_ERR_UNSUPPORTED_PARAM,AVERROR(ENOSYS),  "unsupported param"},
+{ NV_ENC_ERR_LOCK_BUSY,AVERROR(EAGAIN),  "lock busy"},
+{ NV_ENC_ERR_NOT_ENOUGH_BUFFER,AVERROR(ENOBUFS), "not enough buffer"},
+{ NV_ENC_ERR_INVALID_VERSION,  AVERROR(EINVAL),  "invalid version"  },
+{ NV_ENC_ERR_MAP_FAILED,   AVERROR(EIO), "map failed"   },
+{ NV_ENC_ERR_NEED_MORE_INPUT,  AVERROR(EAGAIN),  "need more input"  },
+{ NV_ENC_ERR_ENCODER_BUSY, AVERROR(EAGAIN),  "encoder busy" },
+{ NV_ENC_ERR_EVENT_NOT_REGISTERD,  AVERROR(EBADF),   "event not registered" },
+{ NV_ENC_ERR_GENERIC,  AVERROR_UNKNOWN,  "generic error"},
+{ NV_ENC_ERR_INCOMPATIBLE_CLIENT_KEY,  AVERROR(EINVAL),  "incompatible client key"  },
+{ NV_ENC_ERR_UNIMPLEMENTED,AVERROR(ENOSYS),  "unimplemented"},
+{ NV_ENC_ERR_RESOURCE_REGISTER_FAILED, AVERROR(EIO), "resource register failed" },
+{ NV_ENC_ERR_RESOURCE_NOT_REGISTERED,  AVERROR(EBADF),   "resource not registered"  },
+{ NV_ENC_ERR_RESOURCE_NOT_MAPPED,  AVERROR(EBADF),   "resource not mapped"  },
+};
+
+static int nvenc_map_error(NVENCSTATUS err, const char **desc)
+{
+int i;
+for (i = 0; i < FF_ARRAY_ELEMS(nvenc_errors); i++) {
+if (nvenc_errors[i].nverr == err) {
+if (desc)
+*desc = nvenc_errors[i].desc;
+return nvenc_errors[i].averr;
+}
+}
+if (desc)
+*desc = "unknown error";
+return AVERROR_UNKNOWN;
+}
+
+static int nvenc_print_error(void *log_ctx, NVENCSTATUS err,
+ const char *error_string)
+{
+const char *desc;
+int ret;
+ret = nvenc_map_error(err, );
+av_log(log_ctx, AV_LOG_ERROR, "%s: %s (%d)\n", error_string, desc, err);
+return ret;
+}
+
 static int input_string_to_uint32(AVCodecContext *avctx, const NvencValuePair *pair, const char *input, uint32_t *output)
 {
 for (; pair->str; ++pair) {
@@ -294,7 +344,7 @@ static 

[FFmpeg-devel] [PATCH 1/4] libavcodec/nvenc.c: split large functions into smaller ones

2016-05-20 Thread Andrey Turkin

Functions names and scopes are from libav. This commit basically moves
code around without changing it; it shouldn't change any functionality
except some small leak fixes on error paths.
---
 libavcodec/nvenc.c | 1083 ++--
 1 file changed, 622 insertions(+), 461 deletions(-)

diff --git a/libavcodec/nvenc.c b/libavcodec/nvenc.c
index 104aea0..3d53a0f 100644
--- a/libavcodec/nvenc.c
+++ b/libavcodec/nvenc.c
@@ -541,44 +541,17 @@ static av_cold void nvenc_unload_nvenc(AVCodecContext *avctx)
 av_log(avctx, AV_LOG_VERBOSE, "Nvenc unloaded\n");
 }
 
-static av_cold int nvenc_encode_init(AVCodecContext *avctx)
+static av_cold int nvenc_setup_device(AVCodecContext *avctx)
 {
-NV_ENC_OPEN_ENCODE_SESSION_EX_PARAMS encode_session_params = { 0 };
-NV_ENC_PRESET_CONFIG preset_config = { 0 };
-CUcontext cu_context_curr;
-CUresult cu_res;
-GUID encoder_preset = NV_ENC_PRESET_HQ_GUID;
-GUID codec;
-NVENCSTATUS nv_status = NV_ENC_SUCCESS;
-AVCPBProperties *cpb_props;
-int surfaceCount = 0;
-int i, num_mbs;
-int isLL = 0;
-int lossless = 0;
-int res = 0;
-int dw, dh;
-int qp_inter_p;
-
 NvencContext *ctx = avctx->priv_data;
 NvencDynLoadFunctions *dl_fn = >nvenc_dload_funcs;
-NV_ENCODE_API_FUNCTION_LIST *p_nvenc = _fn->nvenc_funcs;
 
-if (!nvenc_dyload_nvenc(avctx))
-return AVERROR_EXTERNAL;
-
-ctx->last_dts = AV_NOPTS_VALUE;
-
-ctx->encode_config.version = NV_ENC_CONFIG_VER;
-ctx->init_encode_params.version = NV_ENC_INITIALIZE_PARAMS_VER;
-preset_config.version = NV_ENC_PRESET_CONFIG_VER;
-preset_config.presetCfg.version = NV_ENC_CONFIG_VER;
-encode_session_params.version = NV_ENC_OPEN_ENCODE_SESSION_EX_PARAMS_VER;
-encode_session_params.apiVersion = NVENCAPI_VERSION;
+CUresult cu_res;
+CUcontext cu_context_curr;
 
 if (ctx->gpu >= dl_fn->nvenc_device_count) {
 av_log(avctx, AV_LOG_FATAL, "Requested GPU %d, but only %d GPUs are available!\n", ctx->gpu, dl_fn->nvenc_device_count);
-res = AVERROR(EINVAL);
-goto error;
+return AVERROR(EINVAL);
 }
 
 ctx->cu_context = NULL;
@@ -586,18 +559,30 @@ static av_cold int nvenc_encode_init(AVCodecContext *avctx)
 
 if (cu_res != CUDA_SUCCESS) {
 av_log(avctx, AV_LOG_FATAL, "Failed creating CUDA context for NVENC: 0x%x\n", (int)cu_res);
-res = AVERROR_EXTERNAL;
-goto error;
+return AVERROR_EXTERNAL;
 }
 
 cu_res = dl_fn->cu_ctx_pop_current(_context_curr);
 
 if (cu_res != CUDA_SUCCESS) {
 av_log(avctx, AV_LOG_FATAL, "Failed popping CUDA context: 0x%x\n", (int)cu_res);
-res = AVERROR_EXTERNAL;
-goto error;
+return AVERROR_EXTERNAL;
 }
 
+return 0;
+}
+
+static av_cold int nvenc_open_session(AVCodecContext *avctx)
+{
+NvencContext *ctx = avctx->priv_data;
+NvencDynLoadFunctions *dl_fn = >nvenc_dload_funcs;
+NV_ENCODE_API_FUNCTION_LIST *p_nvenc = _fn->nvenc_funcs;
+
+NV_ENC_OPEN_ENCODE_SESSION_EX_PARAMS encode_session_params = { 0 };
+NVENCSTATUS nv_status;
+
+encode_session_params.version = NV_ENC_OPEN_ENCODE_SESSION_EX_PARAMS_VER;
+encode_session_params.apiVersion = NVENCAPI_VERSION;
 encode_session_params.device = ctx->cu_context;
 encode_session_params.deviceType = NV_ENC_DEVICE_TYPE_CUDA;
 
@@ -605,10 +590,322 @@ static av_cold int nvenc_encode_init(AVCodecContext *avctx)
 if (nv_status != NV_ENC_SUCCESS) {
 ctx->nvencoder = NULL;
 av_log(avctx, AV_LOG_FATAL, "OpenEncodeSessionEx failed: 0x%x\n", (int)nv_status);
-res = AVERROR_EXTERNAL;
-goto error;
+return AVERROR_EXTERNAL;
+}
+
+return 0;
+}
+
+static av_cold void set_constqp(AVCodecContext *avctx)
+{
+NvencContext *ctx = avctx->priv_data;
+
+ctx->encode_config.rcParams.rateControlMode = NV_ENC_PARAMS_RC_CONSTQP;
+ctx->encode_config.rcParams.constQP.qpInterB = avctx->global_quality;
+ctx->encode_config.rcParams.constQP.qpInterP = avctx->global_quality;
+ctx->encode_config.rcParams.constQP.qpIntra = avctx->global_quality;
+}
+
+static av_cold void set_vbr(AVCodecContext *avctx)
+{
+NvencContext *ctx = avctx->priv_data;
+
+ctx->encode_config.rcParams.enableMinQP = 1;
+ctx->encode_config.rcParams.enableMaxQP = 1;
+
+ctx->encode_config.rcParams.minQP.qpInterB = avctx->qmin;
+ctx->encode_config.rcParams.minQP.qpInterP = avctx->qmin;
+ctx->encode_config.rcParams.minQP.qpIntra = avctx->qmin;
+
+ctx->encode_config.rcParams.maxQP.qpInterB = avctx->qmax;
+ctx->encode_config.rcParams.maxQP.qpInterP = avctx->qmax;
+ctx->encode_config.rcParams.maxQP.qpIntra = avctx->qmax;
+}
+
+static av_cold void set_lossless(AVCodecContext *avctx)
+{
+NvencContext *ctx = avctx->priv_data;
+
+ctx->encode_config.rcParams.rateControlMode = NV_ENC_PARAMS_RC_CONSTQP;
+

[FFmpeg-devel] [PATCH] [v2] libavcodec/options.c: handle hw_frames_ctx where necessary

2016-05-20 Thread Andrey Turkin
avcodec_copy_context didn't handle hw_frames_ctx references correctly which 
could cause crashes.
---

Changes from v1: reverted changes to avcodec_free_context


 libavcodec/options.c | 9 +
 1 file changed, 9 insertions(+)

diff --git a/libavcodec/options.c b/libavcodec/options.c
index ea2563b..08c2259 100644
--- a/libavcodec/options.c
+++ b/libavcodec/options.c
@@ -197,6 +197,7 @@ int avcodec_copy_context(AVCodecContext *dest, const 
AVCodecContext *src)
 av_freep(>inter_matrix);
 av_freep(>extradata);
 av_freep(>subtitle_header);
+av_buffer_unref(>hw_frames_ctx);
 
 memcpy(dest, src, sizeof(*dest));
 av_opt_copy(dest, src);
@@ -225,6 +226,7 @@ FF_ENABLE_DEPRECATION_WARNINGS
 dest->inter_matrix= NULL;
 dest->rc_override = NULL;
 dest->subtitle_header = NULL;
+dest->hw_frames_ctx   = NULL;
 
 #define alloc_and_copy_or_fail(obj, size, pad) \
 if (src->obj && size > 0) { \
@@ -245,6 +247,12 @@ FF_ENABLE_DEPRECATION_WARNINGS
 av_assert0(dest->subtitle_header_size == src->subtitle_header_size);
 #undef alloc_and_copy_or_fail
 
+if (src->hw_frames_ctx) {
+dest->hw_frames_ctx = av_buffer_ref(src->hw_frames_ctx);
+if (!dest->hw_frames_ctx)
+goto fail;
+}
+
 return 0;
 
 fail:
@@ -255,6 +263,7 @@ fail:
 av_freep(>subtitle_header);
 dest->subtitle_header_size = 0;
 dest->extradata_size = 0;
+av_buffer_unref(>hw_frames_ctx);
 av_opt_free(dest);
 return AVERROR(ENOMEM);
 }
-- 
2.7.3

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


Re: [FFmpeg-devel] [PATCH] libavcodec/options.c: handle hw_frames_ctx where necessary

2016-05-13 Thread Andrey Turkin
> No: this part of the patch does nothing because it's already unreffed in
the
> avcodec_close() called immediately above.  Maybe the unref should
actually be in
> avcodec_free_context() only (if treating it like rc_override and those
fields),
> but it shouldn't be in both.
I missed that, thank you for pointing it out; so there is no memory leak
then. Whether it should be unrefed on codec close is a matter of opinion;
in my opinion avcodec_close shouldn't touch things that aren't created by
avcodec_open.
However I'm inclined to remove that portion of a patch and let someone else
decide if this behaviour should be changed.
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


Re: [FFmpeg-devel] [PATCH] libavcodec/options.c: handle hw_frames_ctx where necessary

2016-05-13 Thread Andrey Turkin
2016-05-13 10:35 GMT+03:00 wm4 <nfx...@googlemail.com>:

> On Thu, 12 May 2016 22:35:48 +0300
> Andrey Turkin <andrey.tur...@gmail.com> wrote:
>
> > Few functions didn't handle hw_frames_ctx references causing resources
> leaks and even crashes.
> > ---
> >  libavcodec/options.c | 10 ++
> >  1 file changed, 10 insertions(+)
> >
> > diff --git a/libavcodec/options.c b/libavcodec/options.c
> > index ea2563b..8682262 100644
> > --- a/libavcodec/options.c
> > +++ b/libavcodec/options.c
> > @@ -175,6 +175,7 @@ void avcodec_free_context(AVCodecContext **pavctx)
> >  av_freep(>intra_matrix);
> >  av_freep(>inter_matrix);
> >  av_freep(>rc_override);
> > +av_buffer_unref(>hw_frames_ctx);
> >
> >  av_freep(pavctx);
> >  }
>
> I would have thought this is the responsibility of the API user?
>
>
AVCodecContext documentation says it is set by a user but then managed and
owned by libavcodec (which is a logical thing to do for any shared
reference).
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


Re: [FFmpeg-devel] [PATCH 2/3] lavd: add teletext quantizer

2016-01-13 Thread Andrey Turkin
Slicer is a part of the library and as such is under LGPL; in fact FFmpeg
already uses the library to decode DVB teletext.



2016-01-14 1:27 GMT+03:00 Carl Eugen Hoyos <ceho...@ag.or.at>:

> Andrey Turkin  gmail.com> writes:
>
> > Why not use libzvbi's slicer? It should be pretty
> > robust with less-than-ideal signal.
>
> It is not entirely available under LGPL afaict.
>
> Carl Eugen
>
> ___
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


Re: [FFmpeg-devel] [PATCH 2/3] lavd: add teletext quantizer

2016-01-13 Thread Andrey Turkin
2016-01-13 22:32 GMT+03:00 Michael Niedermayer :

> to calculate the phase
>
> the area that has alternating 0/1 values can be correlated with a
> sin() and a cos(), if you consider the 2 resulting values as x and y
> coordinates the angle they form from the origin is the phase.
> (this can be worded simpler using complex numbers)
>
> when above is done its essential that a whole multiple of cycles is
> used the important part is that the used sin(x) and cos(x) vectors are
> orthogonal, that is sum sin(x) * cos(x) over the x values considered is
> 0 cutting them off randomls would break that
> (its also possible to use windowing instead of a exact multiple of cycles)
>
> consider that the phase is 0 so our signal input is exactly
> cos(x) (if we define that as 0°), the dot product of that with cos(x)
> is "1" and sin(x) is 0
> now if our input is shifted by 90deg that is it matches sin(x)
> then the dot product with a cos(x) vector is 0 and sin(x) is 1
> ...
> (also i for simpliity normalized the values, sum of cos(x)*cos(x) for
> x from 0 to n would of course be larger than 1 for a larger n)
>

That should work; I wonder about runtime cost though. sin/cos for a given
frequency can be precomputated; atan2 can be turned to table or something.
Still there'd be about 32 multiplications to get a phase (over 4 periods).
That's more than 25000 multiplications per second per teletext standard.
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


Re: [FFmpeg-devel] [PATCH 2/3] lavd: add teletext quantizer

2016-01-12 Thread Andrey Turkin
Why not use libzvbi's slicer? It should be pretty robust with
less-than-ideal signal.

Regarding your code - is there a need to calculate a frequency? I did
something similar a while back with VBI from TV signal and in my experience:

a) this kind of frequency/phase estimation doesn't work that well on a
noisy signal.
 b) there's really no need to estimate frequency - it's a known constant
(well it depends on a standard but in each standard it is a constant) and
generators usually don't deviate from it; you just need to get a good phase
estimation based on, say, local maxima/minima of run-in bits.

Ideal frequency (or rather period) for WST in your code should be 127530; I
presume 4 last samples are WST so their estimated frequency is pretty far
outside specified 25ppm tolerance. Value of 127590 means  that for the last
bit you get a (127590-127530)/65536*360 phase error which is about 1/3 of
period (still within the sample if initial phase was estimated accurately -
but getting close to the edge). However any additional error in estimated
frequency would cause lost or duplicate bits in the last bits of decoded
data. If SDI data is noisy there's a good chance of that happening (and
noisy SDI is not some theoretical possibility - one of local TV studios has
a rather strange setup where they do several SDI->analog and analog->SDI
conversions; frames coming from their last SDI output are already noisy).

2016-01-13 1:40 GMT+03:00 Marton Balint :

> Getting teletext right from VANC/VBI data is tricky, because the teletext
> clock
> is not synced to the video clock. Therefore we have to first measure the
> frequency of the teletext clock in the reconstructed signal, and then
> resample
> the original data appropriately.
>
> What I do is that I measure the distance between the first and the last
> zero
> crossing (leading edge) in the first 3 (constant) bytes of the input to
> calculate the clock frequency and the starting point of the real teletext
> data.
>
> Based on these I can calculate the offsets where the rest of the signal
> needs
> to be quantized, and I do that by a simple linear interpolation between two
> neighbouring values in the original data, so the resampling method is
> simple
> first order hold.
>
> Fixed point arithmethic is used for frequencies and offsets to improve
> precision.
>
> I guess the DSP minded people can come up with a better way, but it works
> for
> me just fine as it is.
>
> Signed-off-by: Marton Balint 
> ---
>  libavdevice/Makefile  |   2 +-
>  libavdevice/teletext_quantizer.c  | 174
> ++
>  libavdevice/teletext_quantizer.h  |  32 +++
>  tests/fate/libavdevice.mak|   5 +-
>  tests/ref/fate/teletext_quantizer |  22 +
>  5 files changed, 233 insertions(+), 2 deletions(-)
>  create mode 100644 libavdevice/teletext_quantizer.c
>  create mode 100644 libavdevice/teletext_quantizer.h
>  create mode 100644 tests/ref/fate/teletext_quantizer
>
> diff --git a/libavdevice/Makefile b/libavdevice/Makefile
> index f57ec0b..f889b7c 100644
> --- a/libavdevice/Makefile
> +++ b/libavdevice/Makefile
> @@ -69,4 +69,4 @@ SKIPHEADERS-$(CONFIG_V4L2_OUTDEV)+= v4l2-common.h
>  SKIPHEADERS-$(HAVE_ALSA_ASOUNDLIB_H) += alsa.h
>  SKIPHEADERS-$(HAVE_SNDIO_H)  += sndio.h
>
> -TESTPROGS = timefilter
> +TESTPROGS = timefilter teletext_quantizer
> diff --git a/libavdevice/teletext_quantizer.c
> b/libavdevice/teletext_quantizer.c
> new file mode 100644
> index 000..af6dbbf
> --- /dev/null
> +++ b/libavdevice/teletext_quantizer.c
> @@ -0,0 +1,174 @@
> +/*
> + * This file is part of FFmpeg.
> + *
> + * FFmpeg is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2.1 of the License, or (at your option) any later version.
> + *
> + * FFmpeg is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with FFmpeg; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
> 02110-1301 USA
> + */
> +
> +#include "libavutil/common.h"
> +#include "libavutil/mem.h"
> +#include "config.h"
> +#include "teletext_quantizer.h"
> +
> +#define BLACK_LEVEL 16
> +#define WHITE_LEVEL 235
> +#define DATA_ZERO_LEVEL (BLACK_LEVEL)
> +#define DATA_ONE_LEVEL (BLACK_LEVEL + ((WHITE_LEVEL - BLACK_LEVEL) * 2 /
> 3))
> +#define DATA_ZERO_MAX ((DATA_ONE_LEVEL + DATA_ZERO_LEVEL) / 2)
> +#define MAX_FRAMING_CODE_END_POSITION 64
> +
> +#define CLOCK_RUNIN  0xaa
> +#define FRAMING_CODE 0xe4
> +
> +static inline int calc_zerocross(int i, uint8_t y1, uint8_t y2)

Re: [FFmpeg-devel] have some major changes for nvenc support

2016-01-08 Thread Andrey Turkin
2016-01-08 20:25 GMT+03:00 Michael Niedermayer :

> Also slightly orthogonal but if you have 4 filters each written for a
> different hwaccel you can write a generic filter that passes its
> stuff to the appropriate one
> If theres not much shareale code between hw specific filters then this
> might be cleaner than throwing all hw specifc code in one filter
> directly
>
> such seperate filters could use the existing conditional compilation
> code, could be used directly if the user wants to force a specific
> hw type, ...
>
> So we'd have a default filter and then specific ones just in case anyone
needs them. That is a great idea.
Not sure which way is cleaner - to have proxy filter or to lump everything
together in one filter and add extra filter definitions to force specific
hwaccel. Would work either way.

That I'd looking for in the end, though, is to have more "intelligent"
ffmpeg wrt hardware acceleration. I'd much rather prefer to have it
automagically use hwaccel whether possible, in the optimal way, and not
have to describe every detail.
For example, this thread started because NVidia had a specific scenario and
they had to offload scaling to CUDA - and they had to concoct something
arguably messy to make it happen. There's very specialized filter with many
outputs, and you have to use complex_filter and you have to map filter
outputs to output files etc. It would be awesome if they could just do
ffmpeg -i input -s 1920x1080 -c:v nvenc_h264 hd1080.mp4 -s 1280x720 -c:v
nvenc_h264 hd720.mp4 ..., and it'd do scaling on GPU without explicit
instructions.

In my opinion (which might be totally wrong), it would take 4 changes to
make that happen:
- make ffmpeg use avfilter for scaling - i.e. connect scale filter to
filterchain output (unless it already does)
- add another pixelformat for CUDA, add its support to scale, and add it as
a input format for nvenc_h264
- adjust pixelformat negotiation logic in avfilter to make sure it would
select CUDA pixelformat for scale (maybe just preferring hwaccel formats
over software ones would work?)
- add interop filter to perform CPU-GPU and GPU-CPU data transfer - i.e.
convert between hwaccel and corresponding software formats; avfilter would
insert it in appropriate places when negotiating pixel formats (I think it
does something similar with scale). This might be tricky - e.g. in my
example single interop filter needs to be added and its output has to be
shared between all the scale filters. If, say, there were 2 GPUs used in
encoding then there would have to be 2 interop filters. On the plus side
all existing host->device copying code in encoders can be thrown out (or
rather moved in that filter); as well as existing device->host copying code
from ffmpeg_*.c. Also it would make writing new hwaccel-enable filters
easier.

Actually there is one more thing to do - filters would somehow have to
share hwaccel contexts with their neighbour filters as well as filterchain
inputs and outputs.
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


Re: [FFmpeg-devel] Discussion related to the use of a global thread pool rather than the current threading model

2016-01-08 Thread Andrey Turkin
2016-01-08 12:42 GMT+03:00 Carl Eugen Hoyos :

>
> I may have misunderstood myself but I believe the
> issue actually only happens on Windows XP;-)
>
>
I've encountered this issue a while back when trying to do about 20
simultaneous transcodings with some video filters. It was on a high-end CPU
with a lot of cores so every codec and MT-enabled video filter would spawn
a lot of threads - can't remember exact number but hundreds of them. The
threads' stacks would eat up all of the process' address space causing OOM.
It was on Windows 7, and it's something you probably can call real-world
example. I ended up disabling MT everywhere I can to fix that (which was a
right thing to do anyway since my program was already multithreaded and it
could use all the cores anyway). This thread-pool idea sounds reasonable to
me; more reasonable than 8-16 threads per codec anyway.
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


Re: [FFmpeg-devel] have some major changes for nvenc support

2016-01-08 Thread Andrey Turkin
In my opinion this proliferation of various filters which do the same thing
in different way is a configuration headache. There's CPU filters: one for
scaling/format conversion, one for padding, one  for cropping, like 5
different filters for deinterlacing. And now there would be nvresize for
scaling, and we gotta add CUDA-based nvpad and nvdeint if we want to do
some transcoding. Maybe add overlaying too - so nvoverlay. Then there is
OpenCL which can do everything - so 4 more filters for that. And there is
quicksync which I think can do those things, so there would be qsvscale and
qsvdeint. And there is D3D11 video processor which can do those things too
(simultaneously in fact), so there's gotta be
d3d11vascaledeintpadcropoverlay. And then we've got a whole bunch of video
filters which can only do their job on a specific hwaccel platform. Want to
try different hwaccel? Rewrite damn filter string. Want to do something
generic that can be used over different platforms? Can't be done.
Maybe it's just my wishful thinking, but I was wondering for some time if
there can be one "smart" filter to do one specific thing? Say, single
deinterlace filter which can automatically use whichever hwaccel was used
on its input (or whichever will be used on its output)? We've already got
pixel formats which describe particular hwaccel - can't filters decide
which code path to use based on that? And it can have a configuration
option to choose which CPU-based fallback to use (in fact that option can
be used to tweak GPU-based algorithm for platforms which support it).
Same goes for encoders - can't there be "just" h264 encoder? This one's
tough though - you might have dxva decoder, cuda filters and nvenc encoder
and you probably want to keep them all on the same GPU. Or not - maybe you
do want to decode on qsv and encode on nvenc, or maybe vice versa. Probably
single-GPU case is more common so it should try to use same GPU what was
used for decoding and/or filtering, and allow to override with encoder
options (like nvenc allows to specify cuda device to use).
Interop will be a pain though (obviously we'd want to avoid device-host
frame transfers). I'm trying to share d3d11va-decoded frames (nv12 texture)
with OpenCL or CUDA right now,and I've been at it for days with no luck
whatsoever. My last resort now is to write a shader to "draw" (in fact just
copy pixels around) nv12 texture onto another texture in more "common"
format which can be used by OpenCL... There's got to be some easier way
(other than using cuvid to decode  the video), right?

Regards, Andrey

2016-01-08 11:29 GMT+03:00 Roger Pack :

> On 11/5/15, wm4  wrote:
> > On Thu, 5 Nov 2015 16:23:04 +0800
> > Agatha Hu  wrote:
> >
> >> 2) We use AVFrame::opaque field to store a customized ffnvinfo struture
> >> to prevent expensive CPU<->GPU transferration. Without it, the workflow
> >> will be like CPU AVFrame input-->copy to GPU-->do CUDA resizing-->copy
> >> to CPU AVFrame-->copy to GPU-->NVENC encoding. And now it becomes:
> >> CPU AVFrame input-->copy to GPU-->do CUDA resizing-->NVENC encoding.
> >> Our strategy is to check whether AVFrame::opaque is not null AND its
> >> first 128 bytes matches some particular GUID. If so, AVFrame::opaque is
> >> a valid ffnvinfo struture and we read GPU address directly from it
> >> instead of copying data from AVFrame.
> >
> > Please no, not another hack that makes the hw decoding API situation
> > worse. Do this properly and coordinate with Gwenole Beauchesne, who
> > plans improvements into this direction.
>
> Which part are you referring to (though I'll admit putting some stuff
> in libavutil seems a bit suspect).
> It would be nice to have the nvresize filter available anyway, and it
> looks like it mostly just deals with private context variables.
> Cheers!
> -roger-
> ___
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


Re: [FFmpeg-devel] [RESEND][PATCH] Fix buffer allocation in pad filter

2016-01-05 Thread Andrey Turkin
Sure; no-copy padding was broken for some scenarios (namely, left-padding
when target height divides evenly by 32). Lets say I want to use following
filter string: "scale=720x576, pad=880:576:80:0" (scale to 720x576 and add
some black bands on the sides). Pad should be able to allocate buffer for
scale and then just fill remaining area; yet it fails to do so and "Direct
padding impossible allocating new frame" message can be seen in logs (when
log level set to verbose). In this particular case the allocated buffer is
big enough to hold 896x576 image and a few extra bytes; scale filter then
operates on its view of the buffer (720x576 but with pitch of 896).
Interestingly, last row of that view doesn't fit in the buffer (there's
only 720 bytes + a bit of padding and not 880 bytes). So scale does its
thing and then pad checks if there is enough extra space in the buffer for
the padding. There's not; in fact there's no room in the buffer to hold the
view itself - so pad gives up and does another allocation and a copy. So,
basically this patch fixes that.

2016-01-06 0:59 GMT+03:00 Paul B Mahol <one...@gmail.com>:

> On 1/5/16, Andrey Turkin <andrey.tur...@gmail.com> wrote:
> >
> > One extra line must be allocated when adding left padding to make sure
> > that last line in every plane fits in the allocated buffer fully
> > ---
> >  libavfilter/vf_pad.c | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> >
> >
>
> Do you have example this patch fixes?
>
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


[FFmpeg-devel] [RESEND][PATCH] Fix buffer allocation in pad filter

2016-01-05 Thread Andrey Turkin

One extra line must be allocated when adding left padding to make sure
that last line in every plane fits in the allocated buffer fully
---
 libavfilter/vf_pad.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libavfilter/vf_pad.c b/libavfilter/vf_pad.c
index d94ced1..555b318 100644
--- a/libavfilter/vf_pad.c
+++ b/libavfilter/vf_pad.c
@@ -203,7 +203,7 @@ static AVFrame *get_video_buffer(AVFilterLink *inlink, int w, int h)
 
 AVFrame *frame = ff_get_video_buffer(inlink->dst->outputs[0],
  w + (s->w - s->in_w),
- h + (s->h - s->in_h));
+ h + (s->h - s->in_h) + (s->x ? 1 : 0));
 int plane;
 
 if (!frame)
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


[FFmpeg-devel] [PATCH] Fix buffer allocation in pad filter

2015-12-25 Thread Andrey Turkin
One extra line must be allocated when adding left padding to make sure
that last line in every plane fits in the allocated buffer fully
---
 libavfilter/vf_pad.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libavfilter/vf_pad.c b/libavfilter/vf_pad.c
index d94ced1..555b318 100644
--- a/libavfilter/vf_pad.c
+++ b/libavfilter/vf_pad.c
@@ -203,7 +203,7 @@ static AVFrame *get_video_buffer(AVFilterLink *inlink, int 
w, int h)
 
 AVFrame *frame = ff_get_video_buffer(inlink->dst->outputs[0],
  w + (s->w - s->in_w),
- h + (s->h - s->in_h));
+ h + (s->h - s->in_h) + (s->x ? 1 : 
0));
 int plane;
 
 if (!frame)
-- 
2.4.10

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel