Re: [FFmpeg-devel] [PATCH] vaapi_encode: explicitly free buffers after vaEndPicture

2016-06-08 Thread Will Kelleher
On 06/08, Will Kelleher wrote:
> 
> That works for me.  I can update the patch with that warning.  Thanks!
>
Updated patch attached.

>From 3229edf9e52dfd61580209630f20ddef3e39e78e Mon Sep 17 00:00:00 2001
From: Will Kelleher <wkelle...@gogoair.com>
Date: Tue, 7 Jun 2016 20:49:48 -0500
Subject: [PATCH] vaapi_encode: explicitly free buffers after vaEndPicture

otherwise they leak, contrary to what the documentation seems to say.
---
 libavcodec/vaapi_encode.c | 23 +++
 1 file changed, 23 insertions(+)

diff --git a/libavcodec/vaapi_encode.c b/libavcodec/vaapi_encode.c
index 329b33c..01b8c70 100644
--- a/libavcodec/vaapi_encode.c
+++ b/libavcodec/vaapi_encode.c
@@ -370,6 +370,29 @@ static int vaapi_encode_issue(AVCodecContext *avctx,
 goto fail_at_end;
 }
 
+// We free all of the parameter buffers here.
+// This is not consistent with what VAAPI states is required; under
+// vaDestroyBuffer, it says: "Only call this if the buffer is not
+// going to be passed to vaRenderBuffer" [sic; vaRenderPicture].
+// Doing this here is a pragmatic decision to preferentially support
+// the Intel i965 back-end driver, which does not and has never
+// freed the buffers as required by the specification - if we don't
+// free here, memory will leak for every frame submitted when using
+// that driver.
+// If other drivers are supported in future, this decision may need
+// to be revisted - if the driver really has already freed the
+// buffer, doing so here is disaster for thread-safety because we
+// may free buffers which have been allocated in other threads.
+for(i = 0; i < pic->nb_param_buffers; i++) {
+if (pic->param_buffers[i] != VA_INVALID_ID) {
+vas = vaDestroyBuffer(ctx->hwctx->display, pic->param_buffers[i]);
+if (vas != 0) {
+av_log(avctx, AV_LOG_WARNING, "Failed to destroy param buffer 
%d\n",i);
+}
+pic->param_buffers[i] = VA_INVALID_ID;
+}
+}
+
 pic->encode_issued = 1;
 
 if (ctx->issue_mode == ISSUE_MODE_SERIALISE_EVERYTHING)
-- 
2.8.0

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


Re: [FFmpeg-devel] [PATCH] vaapi_encode: explicitly free buffers after vaEndPicture

2016-06-08 Thread Will Kelleher
On 06/08, Mark Thompson wrote:
> On 08/06/16 21:02, Will Kelleher wrote:
> > On 06/08, Mark Thompson wrote:
> >> On 08/06/16 18:23, Will Kelleher wrote:
> >>> Hi all -
> >>>
> >>> I'm experiencing some significant heap growth when encoding with VAAPI on
> >>> my Ivy Bridge hardware.  Based on what I'm seeing from Massif, it seems 
> >>> like
> >>> the parameter buffers allocated in vaapi_encode_make_param_buffer are 
> >>> leaking.
> >>>
> >>> I came across this thread [1] that indicates that vaEndPicture might not 
> >>> be
> >>> freeing the param buffers like the libva documentation says it should.
> >>>
> >>> I also noticed that VLC [2] seems to explicitly call vaDestroyBuffer on 
> >>> the
> >>> param buffers after vaEndPicture.
> >>>
> >>> When I try that, the leak is gone.
> >>
> >> Yes, I wrote essentially the same code on observing the same issue.
> >>
> >> Unfortunately, you need a lot more machinery to do this safely - the 
> >> change makes all buffer operations thread-unsafe (another thread could 
> >> allocate a buffer with the ID you are about to try to destroy).  That 
> >> results in needing VADisplay-global locks around pretty much everything to 
> >> do with buffers (including any time the user makes use of them).
> >>
> >> I don't much like the idea of writing all the code to have locking 
> >> everywhere (including in all user code talking to libavcodec), so I took 
> >> the cowardly approach of doing nothing and hiding behind the documentation 
> >> :/
> >>
> >> Therefore, dunno.  Maybe we should talk to the libva people about it?
> >>
> >> - Mark
> >>
> > Hmm, good point.
> > 
> > I wonder if this is why libmfx seems to open separate va displays for each 
> > encode/decode session.
> 
> libmfx on Linux isn't really a wrapper over VAAPI, it has an entirely 
> separate proprietary driver underneath which does who knows what.
> 

That's not quite true.  It certainly has some special sauce inside, but it 
seems to use libva for some of it (although it is a special? fork).

When you run a libmfx encode you should see the libva init prints, like this:

libva info: VA-API version 0.35.0
libva info: va_getDriverName() returns 0
libva info: Trying to open /usr/lib/dri/i965_drv_video.so
libva info: Found init function __vaDriverInit_0_32
libva info: va_openDriver() returns 0

And I see one of those for each ffmpeg encoding that I start, unlike the vaapi 
encoder, which only opens libva once.

> > Unfortunately unless we can solve this, the encoder is pretty useless for 
> > any long-running encodes.
> > 
> > Talking to the libva people might help, but any fix that requires 
> > modifications to libva/libdrm is
> > less than ideal because it would require people to likely build those 
> > components from source to get
> > a recent enough version for this to work.
> 
> Yeah.  Maybe pragmatic concerns with what we have now should win here - the 
> answer is that we obviously should do this if only the i965 driver is 
> supported (which is mostly true already, though I've tried to not to embed it 
> by making large assumptions like this one).
> 
> > That said... how sure are you about these thread safety concerns?  Did you 
> > witness any instability
> > when you tested your vaDestroyBuffer change?  I've been running an encode 
> > of 12 streams with this
> > patch for 17+ hours now without any issues.  I would have crashed due to 
> > OOM by now without this.
> 
> I didn't, but I never did particularly serious testing with the change (I do 
> not currently have a use case for leaving it encoding something indefinitely).
> 
> The concern is more that any other driver someone tries to use will fall over 
> due to this, not that the i965 one will (given the current setup, I think we 
> believe it won't).
> 
> 
> Ok, I think I'm convinced.  We need a long comment next to it describing all 
> of this problem, though.
> 
> Something like:
> 
> // We free all of the parameter buffers here.
> // This is not consistent with what VAAPI states is required; under
> // vaDestroyBuffer, it says: "Only call this if the buffer is not
> // going to be passed to vaRenderBuffer" [sic; vaRenderPicture].
> // Doing this here is a pragmatic decision to preferentially support
> // the Intel i965 back-end driver, which does not and has never
> // freed the buffers as required by the specification - i

Re: [FFmpeg-devel] [PATCH] vaapi_encode: explicitly free buffers after vaEndPicture

2016-06-08 Thread Will Kelleher
On 06/08, Mark Thompson wrote:
> On 08/06/16 18:23, Will Kelleher wrote:
> > Hi all -
> > 
> > I'm experiencing some significant heap growth when encoding with VAAPI on
> > my Ivy Bridge hardware.  Based on what I'm seeing from Massif, it seems like
> > the parameter buffers allocated in vaapi_encode_make_param_buffer are 
> > leaking.
> > 
> > I came across this thread [1] that indicates that vaEndPicture might not be
> > freeing the param buffers like the libva documentation says it should.
> > 
> > I also noticed that VLC [2] seems to explicitly call vaDestroyBuffer on the
> > param buffers after vaEndPicture.
> > 
> > When I try that, the leak is gone.
> 
> Yes, I wrote essentially the same code on observing the same issue.
> 
> Unfortunately, you need a lot more machinery to do this safely - the change 
> makes all buffer operations thread-unsafe (another thread could allocate a 
> buffer with the ID you are about to try to destroy).  That results in needing 
> VADisplay-global locks around pretty much everything to do with buffers 
> (including any time the user makes use of them).
> 
> I don't much like the idea of writing all the code to have locking everywhere 
> (including in all user code talking to libavcodec), so I took the cowardly 
> approach of doing nothing and hiding behind the documentation :/
> 
> Therefore, dunno.  Maybe we should talk to the libva people about it?
> 
> - Mark
>
Hmm, good point.

I wonder if this is why libmfx seems to open separate va displays for each 
encode/decode session.

Unfortunately unless we can solve this, the encoder is pretty useless for any 
long-running encodes.

Talking to the libva people might help, but any fix that requires modifications 
to libva/libdrm is
less than ideal because it would require people to likely build those 
components from source to get
a recent enough version for this to work.

That said... how sure are you about these thread safety concerns?  Did you 
witness any instability
when you tested your vaDestroyBuffer change?  I've been running an encode of 12 
streams with this
patch for 17+ hours now without any issues.  I would have crashed due to OOM by 
now without this.

will

> ___
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://na01.safelinks.protection.outlook.com/?url=http%3a%2f%2fffmpeg.org%2fmailman%2flistinfo%2fffmpeg-devel=01%7c01%7cwkelleher%40gogoair.com%7c74085da316e24558151d08d38fccdd3a%7c2e6508518649457ea18abc0264c3b7d0%7c1=67%2btJgwLlFuEtAvLgP%2f6FP0Y8WBmzpxyV0lBLXCsCOQ%3d
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


[FFmpeg-devel] [PATCH] vaapi_encode: explicitly free buffers after vaEndPicture

2016-06-08 Thread Will Kelleher
Hi all -

I'm experiencing some significant heap growth when encoding with VAAPI on
my Ivy Bridge hardware.  Based on what I'm seeing from Massif, it seems like
the parameter buffers allocated in vaapi_encode_make_param_buffer are leaking.

I came across this thread [1] that indicates that vaEndPicture might not be
freeing the param buffers like the libva documentation says it should.

I also noticed that VLC [2] seems to explicitly call vaDestroyBuffer on the
param buffers after vaEndPicture.

When I try that, the leak is gone.

Thoughts?

Thanks,

will

1: https://lists.freedesktop.org/archives/libva/2012-July/000952.html
2: https://github.com/BtbN/vlc-vaapi-enc/blob/master/vlc-h264-vaapi-enc.c

---
 libavcodec/vaapi_encode.c | 13 +
 1 file changed, 13 insertions(+)

diff --git a/libavcodec/vaapi_encode.c b/libavcodec/vaapi_encode.c
index 329b33c..6fca815 100644
--- a/libavcodec/vaapi_encode.c
+++ b/libavcodec/vaapi_encode.c
@@ -370,6 +370,19 @@ static int vaapi_encode_issue(AVCodecContext *avctx,
 goto fail_at_end;
 }
 
+// Although the documentation says that vaEndPicture will free these 
buffers,
+// in practice that appears not to be the case. We need to explicitly free
+// them to avoid a massive leak.
+for(i = 0; i < pic->nb_param_buffers; i++) {
+if (pic->param_buffers[i] != VA_INVALID_ID) {
+vas = vaDestroyBuffer(ctx->hwctx->display, pic->param_buffers[i]);
+if (vas != 0) {
+av_log(avctx, AV_LOG_WARNING, "Failed to destroy param buffer 
%d\n",i);
+}
+pic->param_buffers[i] = VA_INVALID_ID;
+}
+}
+
 pic->encode_issued = 1;
 
 if (ctx->issue_mode == ISSUE_MODE_SERIALISE_EVERYTHING)
-- 
2.8.0

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


Re: [FFmpeg-devel] [PATCH v2] hevc: Fix memory leak related to a53_caption data

2016-05-10 Thread Will Kelleher
On 04/08, Will Kelleher wrote:
> 
> The leak is...continuous.  We only noticed it during long running decode
> operations because the amount is small, but it definitely adds up.
>
Hi all,

I finally got some time to revisit this.

In the simple case where we are not decoding the HEVC bitstream, the
parser never frees the caption data.  This patch adds a function
similar to what the H.264 decoder is using to free SEI data. This
gets called near the top of each parse_nal_units run to clear any
SEI data from the previous picture.

This is almost a copy-paste from the H.264 solution.

I would love to get this in, because anyone using an HEVC input with
bitstream caption data is going to see this leak.

Thanks,

will

>From d2aa2530b7d808c3710db7b627b96f4159bef460 Mon Sep 17 00:00:00 2001
From: Will Kelleher <wkelle...@gogoair.com>
Date: Thu, 7 Apr 2016 08:58:31 -0500
Subject: [PATCH] hevc: Fix memory leak related to a53_caption data

Signed-off-by: Will Kelleher <wkelle...@gogoair.com>
---
 libavcodec/hevc.c| 2 ++
 libavcodec/hevc.h| 9 +
 libavcodec/hevc_parser.c | 2 ++
 libavcodec/hevc_sei.c| 7 +++
 4 files changed, 20 insertions(+)

diff --git a/libavcodec/hevc.c b/libavcodec/hevc.c
index d1aa0b0..b478065 100644
--- a/libavcodec/hevc.c
+++ b/libavcodec/hevc.c
@@ -3155,6 +3155,8 @@ static av_cold int hevc_init_context(AVCodecContext 
*avctx)
 s->context_initialized = 1;
 s->eos = 0;
 
+ff_hevc_reset_sei(s);
+
 return 0;
 
 fail:
diff --git a/libavcodec/hevc.h b/libavcodec/hevc.h
index f44fa49..be91010 100644
--- a/libavcodec/hevc.h
+++ b/libavcodec/hevc.h
@@ -1054,6 +1054,15 @@ void ff_hevc_hls_mvd_coding(HEVCContext *s, int x0, int 
y0, int log2_cb_size);
 int ff_hevc_encode_nal_vps(HEVCVPS *vps, unsigned int id,
uint8_t *buf, int buf_size);
 
+/**
+ * Reset SEI values that are stored on the Context.
+ * e.g. Caption data that was extracted during NAL
+ * parsing.
+ *
+ * @param s HEVCContext.
+ */
+void ff_hevc_reset_sei(HEVCContext *s);
+
 extern const uint8_t ff_hevc_qpel_extra_before[4];
 extern const uint8_t ff_hevc_qpel_extra_after[4];
 extern const uint8_t ff_hevc_qpel_extra[4];
diff --git a/libavcodec/hevc_parser.c b/libavcodec/hevc_parser.c
index 1227358..b5633f1 100644
--- a/libavcodec/hevc_parser.c
+++ b/libavcodec/hevc_parser.c
@@ -211,6 +211,8 @@ static inline int parse_nal_units(AVCodecParserContext *s, 
const uint8_t *buf,
 
 h->avctx = avctx;
 
+ff_hevc_reset_sei(h);
+
 if (!buf_size)
 return 0;
 
diff --git a/libavcodec/hevc_sei.c b/libavcodec/hevc_sei.c
index 40685fe..59c5941 100644
--- a/libavcodec/hevc_sei.c
+++ b/libavcodec/hevc_sei.c
@@ -373,3 +373,10 @@ int ff_hevc_decode_nal_sei(HEVCContext *s)
 } while (more_rbsp_data(>HEVClc->gb));
 return 1;
 }
+
+void ff_hevc_reset_sei(HEVCContext *s)
+{
+s->a53_caption_size = 0;
+av_freep(>a53_caption);
+}
+
-- 
2.8.0

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


Re: [FFmpeg-devel] [PATCH] hevc: Fix memory leak related to a53_caption data

2016-04-08 Thread Will Kelleher
On 04/08, Michael Niedermayer wrote:
> On Fri, Apr 08, 2016 at 04:17:56PM -0500, Will Kelleher wrote:
> > On 04/08, Michael Niedermayer wrote:
> > > 
> > > > The a53_caption buffer is normally realloc'd when each sei_nal is
> > > > parsed, and then freed after it gets written to the output frame's
> > > > side data in hevc_frame_start.
> > > 
> > > and if an error happens between it leaks ?
> > > 
> > 
> > If an error occurred after sei nal parsing but before the data was
> > written to the output frame's side_data, it would just stay on the
> > context and get appended to when the following frame's sei nals get
> > parsed, and then the combined caption data of two frames would be
> > attached to the second output frame, I think.
> 
> consider that this might have been the last frame and theres no next

The leak is...continuous.  We only noticed it during long running decode
operations because the amount is small, but it definitely adds up.

> 
> [...]
> -- 
> Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB
> 
> Asymptotically faster algorithms should always be preferred if you have
> asymptotical amounts of data



> ___
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://na01.safelinks.protection.outlook.com/?url=http%3a%2f%2fffmpeg.org%2fmailman%2flistinfo%2fffmpeg-devel=01%7c01%7cwkelleher%40gogoair.com%7c201d2489d79b4ea6838c08d35ff8e113%7c2e6508518649457ea18abc0264c3b7d0%7c1=VkOooHUc6od6QXEY1MVqjikRoQrpDIGJZzLLjbfFu9s%3d

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


Re: [FFmpeg-devel] [PATCH] hevc: Fix memory leak related to a53_caption data

2016-04-08 Thread Will Kelleher
On 04/08, Michael Niedermayer wrote:
> On Fri, Apr 08, 2016 at 10:05:13AM -0500, Will Kelleher wrote:
> > Signed-off-by: Will Kelleher <wkelle...@gogoair.com>
> > ---
> >  libavcodec/hevc_parser.c | 3 +++
> >  1 file changed, 3 insertions(+)
> > 
> > diff --git a/libavcodec/hevc_parser.c b/libavcodec/hevc_parser.c
> > index 4625e61..5558afc 100644
> > --- a/libavcodec/hevc_parser.c
> > +++ b/libavcodec/hevc_parser.c
> > @@ -202,6 +202,9 @@ static inline int parse_nal_units(AVCodecParserContext 
> > *s, const uint8_t *buf,
> >  
> >  gb = >HEVClc->gb;
> >  
> > +h->a53_caption_size = 0;
> > +av_freep(>a53_caption);
> > +
> 
> shouldnt this be in hevc_parser_close() ?
> 
> (actually it probably belongs somewhere closer into hevc as the code
>  allocating should also free but the other allocs are also seperate
>  from the freeing ...)

Let me spend a little more time tracing the hevc decode process - I
probably don't understand this code as well as I should.  I have just been
mirroring the existing h264 implementation of this feature.

The a53_caption buffer is normally realloc'd when each sei_nal is
parsed, and then freed after it gets written to the output frame's
side data in hevc_frame_start.

> 
> [...]
> -- 
> Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB
> 
> Opposition brings concord. Out of discord comes the fairest harmony.
> -- Heraclitus



> ___
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://na01.safelinks.protection.outlook.com/?url=http%3a%2f%2fffmpeg.org%2fmailman%2flistinfo%2fffmpeg-devel=01%7c01%7cwkelleher%40gogoair.com%7c7aa319b8e9d24407b0f708d35fdc8f3a%7c2e6508518649457ea18abc0264c3b7d0%7c1=G%2fCXmmQ3nQspFp%2bYaAEtgR5sPoLSfb2IMhJML7wOZWc%3d

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


[FFmpeg-devel] [PATCH] hevc: Fix memory leak related to a53_caption data

2016-04-08 Thread Will Kelleher
Signed-off-by: Will Kelleher <wkelle...@gogoair.com>
---
 libavcodec/hevc_parser.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/libavcodec/hevc_parser.c b/libavcodec/hevc_parser.c
index 4625e61..5558afc 100644
--- a/libavcodec/hevc_parser.c
+++ b/libavcodec/hevc_parser.c
@@ -202,6 +202,9 @@ static inline int parse_nal_units(AVCodecParserContext *s, 
const uint8_t *buf,
 
 gb = >HEVClc->gb;
 
+h->a53_caption_size = 0;
+av_freep(>a53_caption);
+
 /* set some sane default values */
 s->pict_type = AV_PICTURE_TYPE_I;
 s->key_frame = 0;
-- 
2.8.0

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


Re: [FFmpeg-devel] [PATCH 1/2] qsvenc: Use scene-change hints from source frame if available

2015-12-14 Thread Will Kelleher
On 12/14, Nicolas George wrote:
> Le quartidi 24 frimaire, an CCXXIV, Hendrik Leppkes a écrit :
> > It can be both, ffmpeg also has a mode to forward the source types, if
> > the user really wants that. But its of course not on by default.
> 
> Ok. Then I suggest to fix the commit message: the scene-change hints come
> from the application. And no objection to the patch itself, but I am no
> expert in this area.
>
Agreed, I will change the wording in the commit message.

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


Re: [FFmpeg-devel] [PATCH 1/2] qsvenc: Use scene-change hints from source frame if available

2015-12-14 Thread Will Kelleher
On 12/14, Ivan Uskov wrote:
> Hello Will,
> 
> Friday, December 11, 2015, 6:47:28 PM, you wrote:
> 
> WK> Since adaptive_i support is broken, this allows the QSV encoder to use 
> scene-
> WK> change hints from the input stream if force_key_frames = source is used.  
> The
> WK> result will be improved transcoding quality at scene change boundaries.
> 
> WK> Signed-off-by: Will Kelleher <wkelle...@gogoair.com>
> WK> ---
> WK>  libavcodec/qsvenc.c | 11 +++
> WK>  1 file changed, 11 insertions(+)
> 
> WK> diff --git a/libavcodec/qsvenc.c b/libavcodec/qsvenc.c
> WK> index d00fdff..74e40f7 100644
> WK> --- a/libavcodec/qsvenc.c
> WK> +++ b/libavcodec/qsvenc.c
> WK> @@ -939,6 +939,17 @@ int ff_qsv_encode(AVCodecContext *avctx, 
> QSVEncContext *q,
> WK>  q->set_encode_ctrl_cb(avctx, frame, _frame->enc_ctrl);
> WK>  }
> WK>  
> WK> +if (enc_ctrl) {
> +if (frame->>pict_type == AV_PICTURE_TYPE_I) {
> WK> +enc_ctrl->FrameType = MFX_FRAMETYPE_I | MFX_FRAMETYPE_REF;
> WK> +if (frame->key_frame) {
> WK> +enc_ctrl->FrameType |= MFX_FRAMETYPE_IDR;
> WK> +}
> WK> +} else {
> WK> +enc_ctrl->FrameType = 0;
> WK> +}
> WK> +}
> WK> +
> WK>  do {
> WK>  ret = MFXVideoENCODE_EncodeFrameAsync(q->session, enc_ctrl, 
> surf, bs, );
> WK>  if (ret == MFX_WRN_DEVICE_BUSY) {
> Am  I understanding  right  that suggesting feature is non-optional and will
> active  always? I believe it should have own option to activate because there
> are negative side effects are possible.
>

This feature is only activated if you use the "force_key_frames" option set to
"source".  This isn't an encoder-specific option, it exists at the ffmpeg app
level.

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


[FFmpeg-devel] [PATCH 2/2] ffmpeg: Don't clear input pict_type if force_key_frames is source

2015-12-11 Thread Will Kelleher
The current behavior doesn't forward non-IDR I-frames to the encoder.

Signed-off-by: Will Kelleher <wkelle...@gogoair.com>
---
 ffmpeg.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/ffmpeg.c b/ffmpeg.c
index a866f72..61739a4 100644
--- a/ffmpeg.c
+++ b/ffmpeg.c
@@ -1141,7 +1141,6 @@ static void do_video_out(AVFormatContext *s,
 mux_enc->field_order = AV_FIELD_PROGRESSIVE;
 
 in_picture->quality = enc->global_quality;
-in_picture->pict_type = 0;
 
 pts_time = in_picture->pts != AV_NOPTS_VALUE ?
 in_picture->pts * av_q2d(enc->time_base) : NAN;
@@ -1173,13 +1172,15 @@ static void do_video_out(AVFormatContext *s,
 ost->forced_keyframes_expr_const_values[FKF_N] += 1;
 } else if (   ost->forced_keyframes
&& !strncmp(ost->forced_keyframes, "source", 6)
-   && in_picture->key_frame==1) {
+   && in_picture->pict_type==AV_PICTURE_TYPE_I) {
 forced_keyframe = 1;
 }
 
 if (forced_keyframe) {
 in_picture->pict_type = AV_PICTURE_TYPE_I;
 av_log(NULL, AV_LOG_DEBUG, "Forced keyframe at time %f\n", 
pts_time);
+} else {
+in_picture->pict_type = 0;
 }
 
 update_benchmark(NULL);
-- 
2.6.2

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


Re: [FFmpeg-devel] [PATCH 2/2] ffmpeg: Don't clear input pict_type if force_key_frames is source

2015-12-11 Thread Will Kelleher
On 12/11, Michael Niedermayer wrote:
> On Fri, Dec 11, 2015 at 09:47:29AM -0600, Will Kelleher wrote:
> > The current behavior doesn't forward non-IDR I-frames to the encoder.
> 
> would this not turn every I-type non keyframe into a key frame
> effectively?
> and if so, is that intended ?
> 

Depending on how the codec implementation handles it, maybe.

I need a way to make the encoder aware of non-IDR I-frames.  I can't really
tell if the original intent of the `force_key_frames = source` setting is to
force only IDR, or to generally force intra coding of the frame.

With this change, I'm able to differentiate between I-frames and IDR frames
using the key_frame member, which seems to only be set for IDR frames.  So key
frames are (pict_type == AV_PICTURE_TYPE_I && key_frame) and normal I-frames are
just (pict_type == AV_PICTURE_TYPE_I).

If you think this will cause problems with other codecs, do you have any
advice for an alternate implementation?

Also, can you provide some context for why pict_type is being used instead of
key_frame?  Does key_frame need to be valid for some other functionality?

Thanks,

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


Re: [FFmpeg-devel] [PATCH] qsvenc: write a53 caption data to SEI

2015-11-30 Thread Will Kelleher
On 11/26, Michael Niedermayer wrote:
> 
> I tried to apply this but it seems to doesnt apply cleanly anymore
> id fix the conflicts and apply but i cant test this so i think its
> better if you would fix it
> 

Here is a rebased version.

will
>From 5452911c08cdb8cebe861d38a9c1b12924120d78 Mon Sep 17 00:00:00 2001
From: Will Kelleher <wkelle...@gogoair.com>
Date: Tue, 27 Oct 2015 12:08:45 -0500
Subject: [PATCH] qsvenc: write a53 caption data to SEI

Signed-off-by: Will Kelleher <wkelle...@gogoair.com>
---
 libavcodec/qsv_internal.h |  3 +++
 libavcodec/qsvenc.c   | 39 +---
 libavcodec/qsvenc.h   |  4 +++
 libavcodec/qsvenc_h264.c  | 66 +++
 4 files changed, 108 insertions(+), 4 deletions(-)

diff --git a/libavcodec/qsv_internal.h b/libavcodec/qsv_internal.h
index b9ad199..c235e07 100644
--- a/libavcodec/qsv_internal.h
+++ b/libavcodec/qsv_internal.h
@@ -45,6 +45,8 @@
 
 #define ASYNC_DEPTH_DEFAULT 4   // internal parallelism
 
+#define QSV_MAX_ENC_PAYLOAD 2   // # of mfxEncodeCtrl payloads supported
+
 #define QSV_VERSION_ATLEAST(MAJOR, MINOR)   \
 (MFX_VERSION_MAJOR > (MAJOR) || \
  MFX_VERSION_MAJOR == (MAJOR) && MFX_VERSION_MINOR >= (MINOR))
@@ -52,6 +54,7 @@
 typedef struct QSVFrame {
 AVFrame *frame;
 mfxFrameSurface1 *surface;
+mfxEncodeCtrl enc_ctrl;
 
 mfxFrameSurface1 surface_internal;
 
diff --git a/libavcodec/qsvenc.c b/libavcodec/qsvenc.c
index 25a57f4..d00fdff 100644
--- a/libavcodec/qsvenc.c
+++ b/libavcodec/qsvenc.c
@@ -30,6 +30,7 @@
 #include "libavutil/log.h"
 #include "libavutil/time.h"
 #include "libavutil/imgutils.h"
+#include "libavcodec/bytestream.h"
 
 #include "avcodec.h"
 #include "internal.h"
@@ -753,12 +754,26 @@ int ff_qsv_enc_init(AVCodecContext *avctx, QSVEncContext 
*q)
 return 0;
 }
 
+static void free_encoder_ctrl_payloads(mfxEncodeCtrl* enc_ctrl)
+{
+if (enc_ctrl) {
+int i;
+for (i = 0; i < enc_ctrl->NumPayload && i < QSV_MAX_ENC_PAYLOAD; i++) {
+mfxPayload* pay = enc_ctrl->Payload[i];
+av_free(enc_ctrl->Payload[i]->Data);
+av_free(pay);
+}
+enc_ctrl->NumPayload = 0;
+}
+}
+
 static void clear_unused_frames(QSVEncContext *q)
 {
 QSVFrame *cur = q->work_frames;
 while (cur) {
 if (cur->surface && !cur->surface->Data.Locked) {
 cur->surface = NULL;
+free_encoder_ctrl_payloads(>enc_ctrl);
 av_frame_unref(cur->frame);
 }
 cur = cur->next;
@@ -791,6 +806,11 @@ static int get_free_frame(QSVEncContext *q, QSVFrame **f)
 av_freep();
 return AVERROR(ENOMEM);
 }
+frame->enc_ctrl.Payload = av_mallocz(sizeof(mfxPayload*) * 
QSV_MAX_ENC_PAYLOAD);
+if (!frame->enc_ctrl.Payload) {
+av_freep();
+return AVERROR(ENOMEM);
+}
 *last = frame;
 
 *f = frame;
@@ -799,7 +819,7 @@ static int get_free_frame(QSVEncContext *q, QSVFrame **f)
 }
 
 static int submit_frame(QSVEncContext *q, const AVFrame *frame,
-mfxFrameSurface1 **surface)
+QSVFrame **new_frame)
 {
 QSVFrame *qf;
 int ret;
@@ -860,7 +880,7 @@ static int submit_frame(QSVEncContext *q, const AVFrame 
*frame,
 
 qf->surface->Data.TimeStamp = av_rescale_q(frame->pts, 
q->avctx->time_base, (AVRational){1, 9});
 
-*surface = qf->surface;
+*new_frame = qf;
 
 return 0;
 }
@@ -885,15 +905,21 @@ int ff_qsv_encode(AVCodecContext *avctx, QSVEncContext *q,
 
 mfxFrameSurface1 *surf = NULL;
 mfxSyncPoint sync  = NULL;
+QSVFrame *qsv_frame = NULL;
+mfxEncodeCtrl* enc_ctrl = NULL;
 int ret;
 
 if (frame) {
-ret = submit_frame(q, frame, );
+ret = submit_frame(q, frame, _frame);
 if (ret < 0) {
 av_log(avctx, AV_LOG_ERROR, "Error submitting the frame for 
encoding.\n");
 return ret;
 }
 }
+if (qsv_frame) {
+surf = qsv_frame->surface;
+enc_ctrl = _frame->enc_ctrl;
+}
 
 ret = av_new_packet(_pkt, q->packet_size);
 if (ret < 0) {
@@ -909,8 +935,12 @@ int ff_qsv_encode(AVCodecContext *avctx, QSVEncContext *q,
 bs->Data  = new_pkt.data;
 bs->MaxLength = new_pkt.size;
 
+if (q->set_encode_ctrl_cb) {
+q->set_encode_ctrl_cb(avctx, frame, _frame->enc_ctrl);
+}
+
 do {
-ret = MFXVideoENCODE_EncodeFrameAsync(q->session, NULL, surf, bs, 
);
+ret = MFXVideoENCODE_EncodeFrameAsync(q->session, enc_ctrl, surf, bs, 
);
 if (ret == MFX_WRN_DEVICE_BUSY) {
 av_usleep(500);
 continue;
@@ -1010,6 +1040,7 @@ int ff_qsv_enc_close(AVCodecContext *avctx, QSVEnc

Re: [FFmpeg-devel] [PATCH] qsvenc: Add adaptive_i and adaptive_b toggles

2015-11-30 Thread Will Kelleher
On 11/29, Hendrik Leppkes wrote:
> 
> These options were added in a merge from Libav, no further action
> seems to be required.
> 
Oh, good!

I should probably note for the record that these toggles don't always/ever work.
I was testing on Ivy Bridge hardware and the toggles are "accepted" by the API,
but the GOP size doesn't actually adapt.  Intel has confirmed that they are
broken in the all current releases of the Media SDK [1].  So, be careful.

[1]: https://software.intel.com/en-us/forums/intel-media-sdk/topic/600181

Thanks,

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


Re: [FFmpeg-devel] [PATCH] qsvenc: Add adaptive_i and adaptive_b toggles

2015-11-12 Thread Will Kelleher
> Scene change detection ?
> and
> Content dependant B frame insertion
> 
> And if people agree then please someone submit a patch with it
> ill apply it
>

This sounds good to me.  I will update the patch.

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


Re: [FFmpeg-devel] [PATCH] qsvenc: Add adaptive_i and adaptive_b toggles

2015-11-12 Thread Will Kelleher
> Scene change detection ?
> and
> Content dependant B frame insertion
> 
> And if people agree then please someone submit a patch with it
> ill apply it
> 

New patch.

>From 983fb04e74c133de350da41bd5961f8c840ff327 Mon Sep 17 00:00:00 2001
From: Will Kelleher <wkelle...@gogoair.com>
Date: Tue, 10 Nov 2015 14:30:21 -0600
Subject: [PATCH] qsvenc: Add adaptive_i and adaptive_b toggles

Signed-off-by: Will Kelleher <wkelle...@gogoair.com>
---
 libavcodec/qsvenc.c  | 2 ++
 libavcodec/qsvenc.h  | 2 ++
 libavcodec/qsvenc_h264.c | 2 ++
 3 files changed, 6 insertions(+)

diff --git a/libavcodec/qsvenc.c b/libavcodec/qsvenc.c
index df1f777..5e6ace1 100644
--- a/libavcodec/qsvenc.c
+++ b/libavcodec/qsvenc.c
@@ -173,6 +173,8 @@ static int init_video_param(AVCodecContext *avctx, 
QSVEncContext *q)
 #endif
 #if QSV_VERSION_ATLEAST(1,8)
 q->extco2.LookAheadDS   = q->look_ahead_downsampling;
+q->extco2.AdaptiveI = q->adaptive_i ? MFX_CODINGOPTION_ON : 
MFX_CODINGOPTION_UNKNOWN;
+q->extco2.AdaptiveB = q->adaptive_b ? MFX_CODINGOPTION_ON : 
MFX_CODINGOPTION_UNKNOWN;
 #endif
 
 q->extparam_internal[q->nb_extparam_internal++] = (mfxExtBuffer 
*)>extco2;
diff --git a/libavcodec/qsvenc.h b/libavcodec/qsvenc.h
index 3dd7afe..a5f9463 100644
--- a/libavcodec/qsvenc.h
+++ b/libavcodec/qsvenc.h
@@ -76,6 +76,8 @@ typedef struct QSVEncContext {
 int look_ahead;
 int look_ahead_depth;
 int look_ahead_downsampling;
+int adaptive_i;
+int adaptive_b;
 
 char *load_plugins;
 } QSVEncContext;
diff --git a/libavcodec/qsvenc_h264.c b/libavcodec/qsvenc_h264.c
index 0e5a26c..1febe93 100644
--- a/libavcodec/qsvenc_h264.c
+++ b/libavcodec/qsvenc_h264.c
@@ -97,6 +97,8 @@ static const AVOption options[] = {
 { "slow",NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_TARGETUSAGE_3  
},INT_MIN, INT_MAX, VE, "preset" },
 { "slower",  NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_TARGETUSAGE_2  
},INT_MIN, INT_MAX, VE, "preset" },
 { "veryslow",NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 
MFX_TARGETUSAGE_BEST_QUALITY  }, INT_MIN, INT_MAX, VE, "preset" },
+{ "adaptive_i",  "Scene detection", OFFSET(qsv.adaptive_i), 
AV_OPT_TYPE_BOOL,   {.i64 = 0}, 0, 1, VE},
+{ "adaptive_b",  "Content-dependent B-frame insertion", 
OFFSET(qsv.adaptive_b), AV_OPT_TYPE_BOOL,   {.i64 = 0}, 0, 1, VE},
 
 { NULL },
 };
-- 
2.6.2

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


Re: [FFmpeg-devel] [PATCH] qsvenc: write a53 caption data to SEI

2015-11-11 Thread Will Kelleher
On 11/07, Ivan Uskov wrote:
> Although   the  code  looks  ok  by itself, I believe it is bad idea to place
> H.264-specific   codeto   the   function   which  is  commonfor   all
> encoders.  I believe H.264-specific user data insertion should  locates  into
> the qsvenc_h264.c 
> I.e. there is necessary some kind of 'SetEncodeCtrl' callback which points to
> function into the encoder-specific module.
> I believe if you will define a callback pointer 
> QSVEncContext::SetEncodeCtrlCB,
> setup  it  into  qsv_enc_init()  of the qsvenc_h264.c and call if it non-zero
> from   ff_qsv_encode()  we  will  have  good base to extend add user data for
> MPEG2 later. Else we will get very bulky and ugly ff_qsv_encode().
> I can release something but I hope you will able to catch my idea.
> Please let me know if something is unclear.

Hi Ivan,

Here is an updated patch.  Let me know if this is what you were thinking.

will

>From bbe29adf8eedf7944241c7e5e2704a2c8163faf5 Mon Sep 17 00:00:00 2001
From: Will Kelleher <wkelle...@gogoair.com>
Date: Tue, 27 Oct 2015 12:08:45 -0500
Subject: [PATCH] qsvenc: write a53 caption data to SEI

---
 libavcodec/qsv_internal.h |  3 +++
 libavcodec/qsvenc.c   | 39 ---
 libavcodec/qsvenc.h   |  5 
 libavcodec/qsvenc_h264.c  | 67 ++-
 4 files changed, 109 insertions(+), 5 deletions(-)

diff --git a/libavcodec/qsv_internal.h b/libavcodec/qsv_internal.h
index b9ad199..c235e07 100644
--- a/libavcodec/qsv_internal.h
+++ b/libavcodec/qsv_internal.h
@@ -45,6 +45,8 @@
 
 #define ASYNC_DEPTH_DEFAULT 4   // internal parallelism
 
+#define QSV_MAX_ENC_PAYLOAD 2   // # of mfxEncodeCtrl payloads supported
+
 #define QSV_VERSION_ATLEAST(MAJOR, MINOR)   \
 (MFX_VERSION_MAJOR > (MAJOR) || \
  MFX_VERSION_MAJOR == (MAJOR) && MFX_VERSION_MINOR >= (MINOR))
@@ -52,6 +54,7 @@
 typedef struct QSVFrame {
 AVFrame *frame;
 mfxFrameSurface1 *surface;
+mfxEncodeCtrl enc_ctrl;
 
 mfxFrameSurface1 surface_internal;
 
diff --git a/libavcodec/qsvenc.c b/libavcodec/qsvenc.c
index df1f777..73789b5 100644
--- a/libavcodec/qsvenc.c
+++ b/libavcodec/qsvenc.c
@@ -30,6 +30,7 @@
 #include "libavutil/log.h"
 #include "libavutil/time.h"
 #include "libavutil/imgutils.h"
+#include "libavcodec/bytestream.h"
 
 #include "avcodec.h"
 #include "internal.h"
@@ -370,12 +371,26 @@ int ff_qsv_enc_init(AVCodecContext *avctx, QSVEncContext 
*q)
 return 0;
 }
 
+static void free_encoder_ctrl_payloads(mfxEncodeCtrl* enc_ctrl)
+{
+if (enc_ctrl) {
+int i;
+for (i = 0; i < enc_ctrl->NumPayload && i < QSV_MAX_ENC_PAYLOAD; i++) {
+mfxPayload* pay = enc_ctrl->Payload[i];
+av_free(enc_ctrl->Payload[i]->Data);
+av_free(pay);
+}
+enc_ctrl->NumPayload = 0;
+}
+}
+
 static void clear_unused_frames(QSVEncContext *q)
 {
 QSVFrame *cur = q->work_frames;
 while (cur) {
 if (cur->surface && !cur->surface->Data.Locked) {
 cur->surface = NULL;
+free_encoder_ctrl_payloads(>enc_ctrl);
 av_frame_unref(cur->frame);
 }
 cur = cur->next;
@@ -408,6 +423,11 @@ static int get_free_frame(QSVEncContext *q, QSVFrame **f)
 av_freep();
 return AVERROR(ENOMEM);
 }
+frame->enc_ctrl.Payload = av_mallocz(sizeof(mfxPayload*) * 
QSV_MAX_ENC_PAYLOAD);
+if (!frame->enc_ctrl.Payload) {
+av_freep();
+return AVERROR(ENOMEM);
+}
 *last = frame;
 
 *f = frame;
@@ -416,7 +436,7 @@ static int get_free_frame(QSVEncContext *q, QSVFrame **f)
 }
 
 static int submit_frame(QSVEncContext *q, const AVFrame *frame,
-mfxFrameSurface1 **surface)
+QSVFrame **new_frame)
 {
 QSVFrame *qf;
 int ret;
@@ -477,7 +497,7 @@ static int submit_frame(QSVEncContext *q, const AVFrame 
*frame,
 
 qf->surface->Data.TimeStamp = av_rescale_q(frame->pts, 
q->avctx->time_base, (AVRational){1, 9});
 
-*surface = qf->surface;
+*new_frame = qf;
 
 return 0;
 }
@@ -502,15 +522,21 @@ int ff_qsv_encode(AVCodecContext *avctx, QSVEncContext *q,
 
 mfxFrameSurface1 *surf = NULL;
 mfxSyncPoint sync  = NULL;
+QSVFrame *qsv_frame = NULL;
+mfxEncodeCtrl* enc_ctrl = NULL;
 int ret;
 
 if (frame) {
-ret = submit_frame(q, frame, );
+ret = submit_frame(q, frame, _frame);
 if (ret < 0) {
 av_log(avctx, AV_LOG_ERROR, "Error submitting the frame for 
encoding.\n");
 return ret;
 }
 }
+if (qsv_frame) {
+surf = qsv_frame->surface;
+enc_ctrl = _frame->enc_ctrl;
+}
 
 ret = av_new_packet(_pkt, q->p

[FFmpeg-devel] [PATCH] hevc: Fix a53 caption extraction

2015-11-11 Thread Will Kelleher
Just realized my previous patch doesn't work quite right.  I uploaded a better
sample file that actually has visible captions to /incoming/hevc_cc.ts.  I
tested with that file doing hevc->x264 and it works.

This is basically an exact copy of the existing h264 logic.

will

Signed-off-by: Will Kelleher <wkelle...@gogoair.com>
---
 libavcodec/hevc.c |  1 +
 libavcodec/hevc_sei.c | 27 +--
 2 files changed, 18 insertions(+), 10 deletions(-)

diff --git a/libavcodec/hevc.c b/libavcodec/hevc.c
index 1fa5283..ece36f8 100644
--- a/libavcodec/hevc.c
+++ b/libavcodec/hevc.c
@@ -2573,6 +2573,7 @@ static int set_side_data(HEVCContext *s)
 if (sd)
 memcpy(sd->data, s->a53_caption, s->a53_caption_size);
 av_freep(>a53_caption);
+s->a53_caption_size = 0;
 s->avctx->properties |= FF_CODEC_PROPERTY_CLOSED_CAPTIONS;
 }
 
diff --git a/libavcodec/hevc_sei.c b/libavcodec/hevc_sei.c
index e853067..46cd06b 100644
--- a/libavcodec/hevc_sei.c
+++ b/libavcodec/hevc_sei.c
@@ -151,7 +151,6 @@ static int 
decode_registered_user_data_closed_caption(HEVCContext *s, int size)
 int flag;
 int user_data_type_code;
 int cc_count;
-int i;
 
 GetBitContext *gb = >HEVClc->gb;
 
@@ -170,20 +169,28 @@ static int 
decode_registered_user_data_closed_caption(HEVCContext *s, int size)
 size -= 2;
 
 if (cc_count && size >= cc_count * 3) {
-av_freep(>a53_caption);
-s->a53_caption_size = cc_count * 3;
-
-s->a53_caption = av_malloc(s->a53_caption_size);
-if (!s->a53_caption)
-return(AVERROR(ENOMEM));
-
-for (i = 0; i < s->a53_caption_size; i++) {
-s->a53_caption[i++] = get_bits(gb, 8);
+const uint64_t new_size = (s->a53_caption_size + cc_count
+   * UINT64_C(3));
+int i, ret;
+
+if (new_size > INT_MAX)
+return AVERROR(EINVAL);
+
+/* Allow merging of the cc data from two fields. */
+ret = av_reallocp(>a53_caption, new_size);
+if (ret < 0)
+return ret;
+
+for (i = 0; i < cc_count; i++) {
+s->a53_caption[s->a53_caption_size++] = get_bits(gb, 8);
+s->a53_caption[s->a53_caption_size++] = get_bits(gb, 8);
+s->a53_caption[s->a53_caption_size++] = get_bits(gb, 8);
 }
 skip_bits(gb, 8); // marker_bits
 }
 }
 } else {
+int i;
 for (i = 0; i < size - 1; i++)
 skip_bits(gb, 8);
 }
-- 
2.6.2

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


[FFmpeg-devel] [PATCH] qsvenc: Add adaptive_i and adaptive_b toggles

2015-11-10 Thread Will Kelleher
Signed-off-by: Will Kelleher <wkelle...@gogoair.com>
---
 libavcodec/qsvenc.c  | 2 ++
 libavcodec/qsvenc.h  | 2 ++
 libavcodec/qsvenc_h264.c | 2 ++
 3 files changed, 6 insertions(+)

diff --git a/libavcodec/qsvenc.c b/libavcodec/qsvenc.c
index df1f777..5e6ace1 100644
--- a/libavcodec/qsvenc.c
+++ b/libavcodec/qsvenc.c
@@ -173,6 +173,8 @@ static int init_video_param(AVCodecContext *avctx, 
QSVEncContext *q)
 #endif
 #if QSV_VERSION_ATLEAST(1,8)
 q->extco2.LookAheadDS   = q->look_ahead_downsampling;
+q->extco2.AdaptiveI = q->adaptive_i ? MFX_CODINGOPTION_ON : 
MFX_CODINGOPTION_UNKNOWN;
+q->extco2.AdaptiveB = q->adaptive_b ? MFX_CODINGOPTION_ON : 
MFX_CODINGOPTION_UNKNOWN;
 #endif
 
 q->extparam_internal[q->nb_extparam_internal++] = (mfxExtBuffer 
*)>extco2;
diff --git a/libavcodec/qsvenc.h b/libavcodec/qsvenc.h
index 3dd7afe..a5f9463 100644
--- a/libavcodec/qsvenc.h
+++ b/libavcodec/qsvenc.h
@@ -76,6 +76,8 @@ typedef struct QSVEncContext {
 int look_ahead;
 int look_ahead_depth;
 int look_ahead_downsampling;
+int adaptive_i;
+int adaptive_b;
 
 char *load_plugins;
 } QSVEncContext;
diff --git a/libavcodec/qsvenc_h264.c b/libavcodec/qsvenc_h264.c
index 0e5a26c..507f490 100644
--- a/libavcodec/qsvenc_h264.c
+++ b/libavcodec/qsvenc_h264.c
@@ -97,6 +97,8 @@ static const AVOption options[] = {
 { "slow",NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_TARGETUSAGE_3  
},INT_MIN, INT_MAX, VE, "preset" },
 { "slower",  NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_TARGETUSAGE_2  
},INT_MIN, INT_MAX, VE, "preset" },
 { "veryslow",NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 
MFX_TARGETUSAGE_BEST_QUALITY  }, INT_MIN, INT_MAX, VE, "preset" },
+{ "adaptive_i",  "Use AdaptiveI", OFFSET(qsv.adaptive_i), 
AV_OPT_TYPE_BOOL,   {.i64 = 0}, 0, 1, VE},
+{ "adaptive_b",  "Use AdaptiveB", OFFSET(qsv.adaptive_b), 
AV_OPT_TYPE_BOOL,   {.i64 = 0}, 0, 1, VE},
 
 { NULL },
 };
-- 
2.6.2

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


Re: [FFmpeg-devel] [PATCH] qsvenc: write a53 caption data to SEI

2015-11-09 Thread Will Kelleher
On 11/7/15, 12:32 PM, "ffmpeg-devel on behalf of Ivan Uskov" 
 wrote:



>Hello Will,
>
>Saturday, November 7, 2015, 5:29:15 PM, you wrote:
>
>WK> ---
>WK>  libavcodec/qsvenc.c  | 114
>WK> +--
>WK>  libavcodec/qsvenc.h  |   2 +-
>WK>  libavcodec/qsvenc_h264.c |   2 +-
>WK>  3 files changed, 113 insertions(+), 5 deletions(-)
>
>WK> diff --git a/libavcodec/qsvenc.c b/libavcodec/qsvenc.c
>WK> index df1f777..0ee45f9 100644
>WK> --- a/libavcodec/qsvenc.c
>WK> +++ b/libavcodec/qsvenc.c
>WK> @@ -30,6 +30,7 @@
>WK>  #include "libavutil/log.h"
>WK>  #include "libavutil/time.h"
>WK>  #include "libavutil/imgutils.h"
>WK> +#include "libavcodec/bytestream.h"
>WK>  
>WK>  #include "avcodec.h"
>WK>  #include "internal.h"
>WK> @@ -276,7 +277,7 @@ int ff_qsv_enc_init(AVCodecContext *avctx, 
>QSVEncContext *q)
>WK>  q->param.AsyncDepth = q->async_depth;
>WK>  
>WK>  q->async_fifo = av_fifo_alloc((1 + q->async_depth) *
>WK> -  (sizeof(AVPacket) +
>WK> sizeof(mfxSyncPoint) + sizeof(mfxBitstream*)));
>WK> +  (sizeof(AVPacket) +
>WK> sizeof(mfxSyncPoint) + sizeof(mfxBitstream*) + sizeof(mfxEncodeCtrl*)));
>WK>  if (!q->async_fifo)
>WK>  return AVERROR(ENOMEM);
>WK>  
>WK> @@ -494,6 +495,27 @@ static void print_interlace_msg(AVCodecContext 
>*avctx, QSVEncContext *q)
>WK>  }
>WK>  }
>WK>  
>WK> +static void freep_encoder_ctrl(mfxEncodeCtrl** enc_ptr)
>WK> +{
>WK> +mfxEncodeCtrl* enc_ctrl;
>WK> +
>WK> +if (!enc_ptr)
>WK> +return;
>WK> +
>WK> +enc_ctrl = *enc_ptr;
>WK> +
>WK> +if (enc_ctrl) {
>WK> +int i;
>WK> +for (i = 0; i < enc_ctrl->NumPayload; i++) {
>WK> +av_free(enc_ctrl->Payload[i]->Data);
>WK> +av_freep(_ctrl->Payload[i]);
>WK> +}
>WK> +av_free(enc_ctrl->Payload);
>WK> +av_freep(_ctrl);
>WK> +}
>WK> +*enc_ptr = NULL;
>WK> +}
>WK> +
>WK>  int ff_qsv_encode(AVCodecContext *avctx, QSVEncContext *q,
>WK>AVPacket *pkt, const AVFrame *frame, int *got_packet)
>WK>  {
>WK> @@ -504,6 +526,10 @@ int ff_qsv_encode(AVCodecContext *avctx, 
>QSVEncContext *q,
>WK>  mfxSyncPoint sync  = NULL;
>WK>  int ret;
>WK>  
>WK> +// for A53 CC data
>WK> +mfxEncodeCtrl* enc_ctrl = NULL;
>WK> +AVFrameSideData *side_data = NULL;
>WK> +
>WK>  if (frame) {
>WK>  ret = submit_frame(q, frame, );
>WK>  if (ret < 0) {
>WK> @@ -526,8 +552,83 @@ int ff_qsv_encode(AVCodecContext *avctx, 
>QSVEncContext *q,
>WK>  bs->Data  = new_pkt.data;
>WK>  bs->MaxLength = new_pkt.size;
>WK>  
>+if (q->>a53_cc && frame) {
>WK> +side_data = av_frame_get_side_data(frame, AV_FRAME_DATA_A53_CC);
>WK> +if (side_data) {
>Although   the  code  looks  ok  by itself, I believe it is bad idea to place
>H.264-specific   codeto   the   function   which  is  commonfor   all
>encoders.  I believe H.264-specific user data insertion should  locates  into
>the qsvenc_h264.c 
>I.e. there is necessary some kind of 'SetEncodeCtrl' callback which points to
>function into the encoder-specific module.
>I believe if you will define a callback pointer QSVEncContext::SetEncodeCtrlCB,
>setup  it  into  qsv_enc_init()  of the qsvenc_h264.c and call if it non-zero
>from   ff_qsv_encode()  we  will  have  good base to extend add user data for
>MPEG2 later. Else we will get very bulky and ugly ff_qsv_encode().
>I can release something but I hope you will able to catch my idea.
>Please let me know if something is unclear.

Makes sense.  I will send an updated patch today or tomorrow.  Thanks!

>
>-- 
>Best regards,
> Ivanmailto:ivan.us...@nablet.com
>
>___
>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] Intel QuickSync Video

2015-11-09 Thread Will Kelleher

On 11/6/15, 2:34 PM, "ffmpeg-devel on behalf of Sevan Gelici" 
<ffmpeg-devel-boun...@ffmpeg.org on behalf of sevangel...@gmail.com> wrote:

>@Will Kelleher
>CPU:
>http://ark.intel.com/products/75122/Intel-Core-i7-4770-Processor-8M-Cache-up-to-3_90-GHz
>MediaSDK: Intel-linux-media-ocl_generic_16.4.2.1-39163_64bit.tar.gz (inside
>package of mediaserverstudioessentials2015r6.tar.gz)
>Ubuntu 14.04.3 LTS, Codename:   trusty
>

What does vainfo display?
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


Re: [FFmpeg-devel] [PATCH] hevc: extract SEI caption data

2015-11-09 Thread Will Kelleher
On 11/7/15, 12:07 PM, "ffmpeg-devel on behalf of Michael Niedermayer" 
<ffmpeg-devel-boun...@ffmpeg.org on behalf of mich...@niedermayer.cc> wrote:



>On Sat, Nov 07, 2015 at 02:17:12PM +, Will Kelleher wrote:
>> On 11/7/15, 5:10 AM, "ffmpeg-devel on behalf of Michael Niedermayer" 
>> <ffmpeg-devel-boun...@ffmpeg.org on behalf of mich...@niedermayer.cc> wrote:
>> 
>> 
>> 
>> >On Fri, Nov 06, 2015 at 02:48:46PM -0600, Will Kelleher wrote:
>> >> Signed-off-by: Will Kelleher <wkelle...@gogoair.com>
>> >> ---
>> >>  libavcodec/hevc.c | 10 +++
>> >>  libavcodec/hevc.h |  4 +++
>> >>  libavcodec/hevc_sei.c | 80 
>> >> +++
>> >>  3 files changed, 94 insertions(+)
>> >
>> >Applied
>> 
>> Thanks!
>> 
>> >
>> >do you have a sample that you can share ?
>> 
>> I do have a sample HEVC+AAC TS file.  It’s about 7MB.  Can I upload this to 
>> the FTP server?
>
>yes, please also tell us the filename afer uploading

Just uploaded /incoming/HEVC-CC.ts

>
>thx
>
>[...]
>-- 
>Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB
>
>Opposition brings concord. Out of discord comes the fairest harmony.
>-- Heraclitus
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


[FFmpeg-devel] [PATCH] qsvenc: write a53 caption data to SEI

2015-11-07 Thread Will Kelleher
---
 libavcodec/qsvenc.c  | 114 +--
 libavcodec/qsvenc.h  |   2 +-
 libavcodec/qsvenc_h264.c |   2 +-
 3 files changed, 113 insertions(+), 5 deletions(-)

diff --git a/libavcodec/qsvenc.c b/libavcodec/qsvenc.c
index df1f777..0ee45f9 100644
--- a/libavcodec/qsvenc.c
+++ b/libavcodec/qsvenc.c
@@ -30,6 +30,7 @@
 #include "libavutil/log.h"
 #include "libavutil/time.h"
 #include "libavutil/imgutils.h"
+#include "libavcodec/bytestream.h"
 
 #include "avcodec.h"
 #include "internal.h"
@@ -276,7 +277,7 @@ int ff_qsv_enc_init(AVCodecContext *avctx, QSVEncContext *q)
 q->param.AsyncDepth = q->async_depth;
 
 q->async_fifo = av_fifo_alloc((1 + q->async_depth) *
-  (sizeof(AVPacket) + sizeof(mfxSyncPoint) + 
sizeof(mfxBitstream*)));
+  (sizeof(AVPacket) + sizeof(mfxSyncPoint) + 
sizeof(mfxBitstream*) + sizeof(mfxEncodeCtrl*)));
 if (!q->async_fifo)
 return AVERROR(ENOMEM);
 
@@ -494,6 +495,27 @@ static void print_interlace_msg(AVCodecContext *avctx, 
QSVEncContext *q)
 }
 }
 
+static void freep_encoder_ctrl(mfxEncodeCtrl** enc_ptr)
+{
+mfxEncodeCtrl* enc_ctrl;
+
+if (!enc_ptr)
+return;
+
+enc_ctrl = *enc_ptr;
+
+if (enc_ctrl) {
+int i;
+for (i = 0; i < enc_ctrl->NumPayload; i++) {
+av_free(enc_ctrl->Payload[i]->Data);
+av_freep(_ctrl->Payload[i]);
+}
+av_free(enc_ctrl->Payload);
+av_freep(_ctrl);
+}
+*enc_ptr = NULL;
+}
+
 int ff_qsv_encode(AVCodecContext *avctx, QSVEncContext *q,
   AVPacket *pkt, const AVFrame *frame, int *got_packet)
 {
@@ -504,6 +526,10 @@ int ff_qsv_encode(AVCodecContext *avctx, QSVEncContext *q,
 mfxSyncPoint sync  = NULL;
 int ret;
 
+// for A53 CC data
+mfxEncodeCtrl* enc_ctrl = NULL;
+AVFrameSideData *side_data = NULL;
+
 if (frame) {
 ret = submit_frame(q, frame, );
 if (ret < 0) {
@@ -526,8 +552,83 @@ int ff_qsv_encode(AVCodecContext *avctx, QSVEncContext *q,
 bs->Data  = new_pkt.data;
 bs->MaxLength = new_pkt.size;
 
+if (q->a53_cc && frame) {
+side_data = av_frame_get_side_data(frame, AV_FRAME_DATA_A53_CC);
+if (side_data) {
+
+int sei_payload_size = 0;
+mfxU8* sei_data = NULL;
+mfxPayload* payload = NULL;
+mfxPayload** payloads = NULL;
+
+sei_payload_size = side_data->size + 13;
+
+sei_data = av_mallocz(sei_payload_size);
+if (!sei_data) {
+av_log(avctx, AV_LOG_ERROR, "No memory for CC, skipping...\n");
+goto skip_a53cc;
+}
+
+// SEI header
+sei_data[0] = 4;
+sei_data[1] = sei_payload_size - 2; // size of SEI data
+
+// country code
+sei_data[2] = 181;
+sei_data[3] = 0;
+sei_data[4] = 49;
+
+// ATSC_identifier - using 'GA94' only
+AV_WL32(sei_data + 5,
+MKTAG('G', 'A', '9', '4'));
+sei_data[9] = 3;
+sei_data[10] =
+((side_data->size/3) & 0x1f) | 0xC0;
+
+sei_data[11] = 0xFF; // reserved
+
+memcpy(sei_data + 12, side_data->data, side_data->size);
+
+sei_data[side_data->size+12] = 255;
+
+payload = av_mallocz(sizeof(mfxPayload));
+if (!payload) {
+av_log(avctx, AV_LOG_ERROR, "No memory, skipping captions\n");
+av_freep(_data);
+goto skip_a53cc;
+}
+payload->BufSize = side_data->size + 13;
+payload->NumBit = payload->BufSize * 8;
+payload->Type = 4;
+payload->Data = sei_data;
+
+payloads = av_mallocz(sizeof(mfxPayload*));
+if (!payloads) {
+av_log(avctx, AV_LOG_ERROR, "No memory, skipping captions\n");
+av_freep(_data);
+av_freep();
+goto skip_a53cc;
+}
+
+payloads[0] = payload;
+
+enc_ctrl = av_mallocz(sizeof(mfxEncodeCtrl));
+if (!enc_ctrl)
+{
+av_log(avctx, AV_LOG_VERBOSE, "No memory for mfxEncodeCtrl\n");
+av_freep(_data);
+av_freep();
+av_freep();
+goto skip_a53cc;
+}
+enc_ctrl->NumExtParam = 0;
+enc_ctrl->NumPayload = 0;
+enc_ctrl->Payload = payloads;
+   }
+}
+skip_a53cc:
 do {
-ret = MFXVideoENCODE_EncodeFrameAsync(q->session, NULL, surf, bs, 
);
+ret = MFXVideoENCODE_EncodeFrameAsync(q->session, enc_ctrl, surf, bs, 
);
 if (ret == MFX_WRN_DEVICE_BUSY) {
 av_usleep(500);
 continue;
@@ -554,10 +655,12 @@ int ff_qsv_encode(AVCodecContext *avctx, QSVEncContext *q,
 if (sync) {
  

Re: [FFmpeg-devel] [PATCH] hevc: extract SEI caption data

2015-11-07 Thread Will Kelleher
On 11/7/15, 5:10 AM, "ffmpeg-devel on behalf of Michael Niedermayer" 
<ffmpeg-devel-boun...@ffmpeg.org on behalf of mich...@niedermayer.cc> wrote:



>On Fri, Nov 06, 2015 at 02:48:46PM -0600, Will Kelleher wrote:
>> Signed-off-by: Will Kelleher <wkelle...@gogoair.com>
>> ---
>>  libavcodec/hevc.c | 10 +++
>>  libavcodec/hevc.h |  4 +++
>>  libavcodec/hevc_sei.c | 80 
>> +++
>>  3 files changed, 94 insertions(+)
>
>Applied

Thanks!

>
>do you have a sample that you can share ?

I do have a sample HEVC+AAC TS file.  It’s about 7MB.  Can I upload this to the 
FTP server?

>
>thanks
>
>[...]
>-- 
>Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB
>
>Why not whip the teacher when the pupil misbehaves? -- Diogenes of Sinope
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


Re: [FFmpeg-devel] Intel QuickSync Video

2015-11-06 Thread Will Kelleher
> Hello,
> 
> I try to transcode with quick sync, but it doesn't work.
> I did follow:  https://ffmpeg.org/general.html#Intel-QuickSync-Video
>
> 
> I get this error
> [h264_qsv @ 0x3017580] Error initializing an internal MFX session
> Error while opening encoder for output stream #0:0 - maybe incorrect
> parameters such as bit_rate, rate, width or height
> 
> How can I solve this please?

Unfortunately this error can be caused by a variety of things.  To start, can
you share your exact CPU model and the Media SDK version that you're using?

Also, what platform are you on?

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


[FFmpeg-devel] [PATCH] hevc: extract SEI caption data

2015-11-06 Thread Will Kelleher
Signed-off-by: Will Kelleher <wkelle...@gogoair.com>
---
 libavcodec/hevc.c | 10 +++
 libavcodec/hevc.h |  4 +++
 libavcodec/hevc_sei.c | 79 +++
 3 files changed, 93 insertions(+)

diff --git a/libavcodec/hevc.c b/libavcodec/hevc.c
index 4b3f199..1fa5283 100644
--- a/libavcodec/hevc.c
+++ b/libavcodec/hevc.c
@@ -2566,6 +2566,16 @@ static int set_side_data(HEVCContext *s)
s->sei_hflip, s->sei_vflip);
 }
 
+if (s->a53_caption) {
+AVFrameSideData* sd = av_frame_new_side_data(out,
+ AV_FRAME_DATA_A53_CC,
+ s->a53_caption_size);
+if (sd)
+memcpy(sd->data, s->a53_caption, s->a53_caption_size);
+av_freep(>a53_caption);
+s->avctx->properties |= FF_CODEC_PROPERTY_CLOSED_CAPTIONS;
+}
+
 return 0;
 }
 
diff --git a/libavcodec/hevc.h b/libavcodec/hevc.h
index 66b9a2f..6d8f703 100644
--- a/libavcodec/hevc.h
+++ b/libavcodec/hevc.h
@@ -937,6 +937,10 @@ typedef struct HEVCContext {
 int sei_hflip, sei_vflip;
 
 int picture_struct;
+
+uint8_t* a53_caption;
+int a53_caption_size;
+
 } HEVCContext;
 
 int ff_hevc_decode_short_term_rps(GetBitContext *gb, AVCodecContext *avctx,
diff --git a/libavcodec/hevc_sei.c b/libavcodec/hevc_sei.c
index 179b045..0e56859 100644
--- a/libavcodec/hevc_sei.c
+++ b/libavcodec/hevc_sei.c
@@ -146,6 +146,83 @@ static int decode_pic_timing(HEVCContext *s)
 return 1;
 }
 
+static int decode_registered_user_data_closed_caption(HEVCContext *s, int size)
+{
+   int flag;
+   int user_data_type_code;
+   int cc_count;
+
+   GetBitContext *gb = >HEVClc->gb;
+
+   if (size < 3)
+   return AVERROR(EINVAL);
+
+   user_data_type_code = get_bits(gb, 8);
+   if (user_data_type_code == 0x3) {
+   skip_bits(gb, 1); // reserved
+
+   flag = get_bits(gb, 1); // process_cc_data_flag
+   if (flag) {
+   skip_bits(gb, 1);
+   cc_count = get_bits(gb, 5);
+   skip_bits(gb, 8); // reserved
+   size -= 2;
+
+   if (cc_count && size >= cc_count * 3) {
+   if (s->a53_caption)
+   av_freep(>a53_caption);
+   s->a53_caption_size = cc_count * 3;
+
+   s->a53_caption = av_malloc(s->a53_caption_size);
+
+   int i;
+   for (i = 0; i < s->a53_caption_size; i++) {
+   s->a53_caption[i++] = get_bits(gb, 8);
+   }
+   skip_bits(gb, 8); // marker_bits
+   }
+   }
+   } else {
+   int i;
+   for (i = 0; i < size - 1; i++)
+   skip_bits(gb, 8);
+   }
+
+   return 0;
+}
+
+static int decode_nal_sei_user_data_registered_itu_t_t35(HEVCContext *s, int 
size)
+{
+uint32_t country_code;
+uint32_t user_identifier;
+
+GetBitContext *gb = >HEVClc->gb;
+
+if (size < 7)
+return AVERROR(EINVAL);
+size -= 7;
+
+country_code = get_bits(gb, 8);
+if (country_code == 0xFF) {
+skip_bits(gb, 8);
+size--;
+}
+
+skip_bits(gb, 8);
+skip_bits(gb, 8);
+
+user_identifier = get_bits_long(gb, 32);
+
+switch (user_identifier) {
+case MKBETAG('G', 'A', '9', '4'):
+return decode_registered_user_data_closed_caption(s, size);
+default:
+skip_bits(gb, size * 8);
+break;
+}
+return 0;
+}
+
 static int active_parameter_sets(HEVCContext *s)
 {
 GetBitContext *gb = >HEVClc->gb;
@@ -198,6 +275,8 @@ static int decode_nal_sei_prefix(HEVCContext *s, int type, 
int size)
 active_parameter_sets(s);
 av_log(s->avctx, AV_LOG_DEBUG, "Skipped PREFIX SEI %d\n", type);
 return 0;
+case SEI_TYPE_USER_DATA_REGISTERED_ITU_T_T35:
+return decode_nal_sei_user_data_registered_itu_t_t35(s, size);
 default:
 av_log(s->avctx, AV_LOG_DEBUG, "Skipped PREFIX SEI %d\n", type);
 skip_bits_long(gb, 8 * size);
-- 
2.6.2

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


[FFmpeg-devel] [PATCH] hevc: extract SEI caption data

2015-11-06 Thread Will Kelleher
Signed-off-by: Will Kelleher <wkelle...@gogoair.com>
---
 libavcodec/hevc.c | 10 +++
 libavcodec/hevc.h |  4 +++
 libavcodec/hevc_sei.c | 80 +++
 3 files changed, 94 insertions(+)

diff --git a/libavcodec/hevc.c b/libavcodec/hevc.c
index 4b3f199..1fa5283 100644
--- a/libavcodec/hevc.c
+++ b/libavcodec/hevc.c
@@ -2566,6 +2566,16 @@ static int set_side_data(HEVCContext *s)
s->sei_hflip, s->sei_vflip);
 }
 
+if (s->a53_caption) {
+AVFrameSideData* sd = av_frame_new_side_data(out,
+ AV_FRAME_DATA_A53_CC,
+ s->a53_caption_size);
+if (sd)
+memcpy(sd->data, s->a53_caption, s->a53_caption_size);
+av_freep(>a53_caption);
+s->avctx->properties |= FF_CODEC_PROPERTY_CLOSED_CAPTIONS;
+}
+
 return 0;
 }
 
diff --git a/libavcodec/hevc.h b/libavcodec/hevc.h
index 66b9a2f..6d8f703 100644
--- a/libavcodec/hevc.h
+++ b/libavcodec/hevc.h
@@ -937,6 +937,10 @@ typedef struct HEVCContext {
 int sei_hflip, sei_vflip;
 
 int picture_struct;
+
+uint8_t* a53_caption;
+int a53_caption_size;
+
 } HEVCContext;
 
 int ff_hevc_decode_short_term_rps(GetBitContext *gb, AVCodecContext *avctx,
diff --git a/libavcodec/hevc_sei.c b/libavcodec/hevc_sei.c
index 179b045..47ba70d 100644
--- a/libavcodec/hevc_sei.c
+++ b/libavcodec/hevc_sei.c
@@ -146,6 +146,84 @@ static int decode_pic_timing(HEVCContext *s)
 return 1;
 }
 
+static int decode_registered_user_data_closed_caption(HEVCContext *s, int size)
+{
+int flag;
+int user_data_type_code;
+int cc_count;
+
+GetBitContext *gb = >HEVClc->gb;
+
+if (size < 3)
+   return AVERROR(EINVAL);
+
+user_data_type_code = get_bits(gb, 8);
+if (user_data_type_code == 0x3) {
+skip_bits(gb, 1); // reserved
+
+flag = get_bits(gb, 1); // process_cc_data_flag
+if (flag) {
+skip_bits(gb, 1);
+cc_count = get_bits(gb, 5);
+skip_bits(gb, 8); // reserved
+size -= 2;
+
+if (cc_count && size >= cc_count * 3) {
+av_freep(>a53_caption);
+s->a53_caption_size = cc_count * 3;
+
+s->a53_caption = av_malloc(s->a53_caption_size);
+if (!s->a53_caption)
+return(AVERROR(ENOMEM));
+
+int i;
+for (i = 0; i < s->a53_caption_size; i++) {
+s->a53_caption[i++] = get_bits(gb, 8);
+}
+skip_bits(gb, 8); // marker_bits
+}
+}
+} else {
+int i;
+for (i = 0; i < size - 1; i++)
+skip_bits(gb, 8);
+}
+
+return 0;
+}
+
+static int decode_nal_sei_user_data_registered_itu_t_t35(HEVCContext *s, int 
size)
+{
+uint32_t country_code;
+uint32_t user_identifier;
+
+GetBitContext *gb = >HEVClc->gb;
+
+if (size < 7)
+return AVERROR(EINVAL);
+size -= 7;
+
+country_code = get_bits(gb, 8);
+if (country_code == 0xFF) {
+skip_bits(gb, 8);
+size--;
+}
+
+skip_bits(gb, 8);
+skip_bits(gb, 8);
+
+user_identifier = get_bits_long(gb, 32);
+
+switch (user_identifier) {
+case MKBETAG('G', 'A', '9', '4'):
+return decode_registered_user_data_closed_caption(s, size);
+default:
+skip_bits_long(gb, size * 8);
+break;
+}
+return 0;
+}
+
 static int active_parameter_sets(HEVCContext *s)
 {
 GetBitContext *gb = >HEVClc->gb;
@@ -198,6 +276,8 @@ static int decode_nal_sei_prefix(HEVCContext *s, int type, 
int size)
 active_parameter_sets(s);
 av_log(s->avctx, AV_LOG_DEBUG, "Skipped PREFIX SEI %d\n", type);
 return 0;
+case SEI_TYPE_USER_DATA_REGISTERED_ITU_T_T35:
+return decode_nal_sei_user_data_registered_itu_t_t35(s, size);
 default:
 av_log(s->avctx, AV_LOG_DEBUG, "Skipped PREFIX SEI %d\n", type);
 skip_bits_long(gb, 8 * size);
-- 
2.6.2

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


[FFmpeg-devel] [PATCH] hevc: extract SEI caption data

2015-11-06 Thread Will Kelleher
Signed-off-by: Will Kelleher <wkelle...@gogoair.com>
---
 libavcodec/hevc.c | 10 +++
 libavcodec/hevc.h |  4 +++
 libavcodec/hevc_sei.c | 80 +++
 3 files changed, 94 insertions(+)

diff --git a/libavcodec/hevc.c b/libavcodec/hevc.c
index 4b3f199..1fa5283 100644
--- a/libavcodec/hevc.c
+++ b/libavcodec/hevc.c
@@ -2566,6 +2566,16 @@ static int set_side_data(HEVCContext *s)
s->sei_hflip, s->sei_vflip);
 }
 
+if (s->a53_caption) {
+AVFrameSideData* sd = av_frame_new_side_data(out,
+ AV_FRAME_DATA_A53_CC,
+ s->a53_caption_size);
+if (sd)
+memcpy(sd->data, s->a53_caption, s->a53_caption_size);
+av_freep(>a53_caption);
+s->avctx->properties |= FF_CODEC_PROPERTY_CLOSED_CAPTIONS;
+}
+
 return 0;
 }
 
diff --git a/libavcodec/hevc.h b/libavcodec/hevc.h
index 66b9a2f..6d8f703 100644
--- a/libavcodec/hevc.h
+++ b/libavcodec/hevc.h
@@ -937,6 +937,10 @@ typedef struct HEVCContext {
 int sei_hflip, sei_vflip;
 
 int picture_struct;
+
+uint8_t* a53_caption;
+int a53_caption_size;
+
 } HEVCContext;
 
 int ff_hevc_decode_short_term_rps(GetBitContext *gb, AVCodecContext *avctx,
diff --git a/libavcodec/hevc_sei.c b/libavcodec/hevc_sei.c
index 179b045..4132634 100644
--- a/libavcodec/hevc_sei.c
+++ b/libavcodec/hevc_sei.c
@@ -146,6 +146,84 @@ static int decode_pic_timing(HEVCContext *s)
 return 1;
 }
 
+static int decode_registered_user_data_closed_caption(HEVCContext *s, int size)
+{
+int flag;
+int user_data_type_code;
+int cc_count;
+
+GetBitContext *gb = >HEVClc->gb;
+
+if (size < 3)
+   return AVERROR(EINVAL);
+
+user_data_type_code = get_bits(gb, 8);
+if (user_data_type_code == 0x3) {
+skip_bits(gb, 1); // reserved
+
+flag = get_bits(gb, 1); // process_cc_data_flag
+if (flag) {
+skip_bits(gb, 1);
+cc_count = get_bits(gb, 5);
+skip_bits(gb, 8); // reserved
+size -= 2;
+
+if (cc_count && size >= cc_count * 3) {
+av_freep(>a53_caption);
+s->a53_caption_size = cc_count * 3;
+
+s->a53_caption = av_malloc(s->a53_caption_size);
+if (!s->a53_caption)
+return(AVERROR(ENOMEM));
+
+int i;
+for (i = 0; i < s->a53_caption_size; i++) {
+s->a53_caption[i++] = get_bits(gb, 8);
+}
+skip_bits(gb, 8); // marker_bits
+}
+}
+} else {
+int i;
+for (i = 0; i < size - 1; i++)
+skip_bits_long(gb, 8);
+}
+
+return 0;
+}
+
+static int decode_nal_sei_user_data_registered_itu_t_t35(HEVCContext *s, int 
size)
+{
+uint32_t country_code;
+uint32_t user_identifier;
+
+GetBitContext *gb = >HEVClc->gb;
+
+if (size < 7)
+return AVERROR(EINVAL);
+size -= 7;
+
+country_code = get_bits(gb, 8);
+if (country_code == 0xFF) {
+skip_bits(gb, 8);
+size--;
+}
+
+skip_bits(gb, 8);
+skip_bits(gb, 8);
+
+user_identifier = get_bits_long(gb, 32);
+
+switch (user_identifier) {
+case MKBETAG('G', 'A', '9', '4'):
+return decode_registered_user_data_closed_caption(s, size);
+default:
+skip_bits(gb, size * 8);
+break;
+}
+return 0;
+}
+
 static int active_parameter_sets(HEVCContext *s)
 {
 GetBitContext *gb = >HEVClc->gb;
@@ -198,6 +276,8 @@ static int decode_nal_sei_prefix(HEVCContext *s, int type, 
int size)
 active_parameter_sets(s);
 av_log(s->avctx, AV_LOG_DEBUG, "Skipped PREFIX SEI %d\n", type);
 return 0;
+case SEI_TYPE_USER_DATA_REGISTERED_ITU_T_T35:
+return decode_nal_sei_user_data_registered_itu_t_t35(s, size);
 default:
 av_log(s->avctx, AV_LOG_DEBUG, "Skipped PREFIX SEI %d\n", type);
 skip_bits_long(gb, 8 * size);
-- 
2.6.2

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


[FFmpeg-devel] [PATCH] hevc: extract SEI caption data

2015-11-05 Thread Will Kelleher
Signed-off-by: Will Kelleher <wkelle...@gogoair.com>
---
 libavcodec/hevc.c | 10 +++
 libavcodec/hevc.h |  4 +++
 libavcodec/hevc_sei.c | 79 +++
 3 files changed, 93 insertions(+)

diff --git a/libavcodec/hevc.c b/libavcodec/hevc.c
index 4b3f199..1fa5283 100644
--- a/libavcodec/hevc.c
+++ b/libavcodec/hevc.c
@@ -2566,6 +2566,16 @@ static int set_side_data(HEVCContext *s)
s->sei_hflip, s->sei_vflip);
 }
 
+if (s->a53_caption) {
+AVFrameSideData* sd = av_frame_new_side_data(out,
+ AV_FRAME_DATA_A53_CC,
+ s->a53_caption_size);
+if (sd)
+memcpy(sd->data, s->a53_caption, s->a53_caption_size);
+av_freep(>a53_caption);
+s->avctx->properties |= FF_CODEC_PROPERTY_CLOSED_CAPTIONS;
+}
+
 return 0;
 }
 
diff --git a/libavcodec/hevc.h b/libavcodec/hevc.h
index 66b9a2f..6d8f703 100644
--- a/libavcodec/hevc.h
+++ b/libavcodec/hevc.h
@@ -937,6 +937,10 @@ typedef struct HEVCContext {
 int sei_hflip, sei_vflip;
 
 int picture_struct;
+
+uint8_t* a53_caption;
+int a53_caption_size;
+
 } HEVCContext;
 
 int ff_hevc_decode_short_term_rps(GetBitContext *gb, AVCodecContext *avctx,
diff --git a/libavcodec/hevc_sei.c b/libavcodec/hevc_sei.c
index 179b045..0e56859 100644
--- a/libavcodec/hevc_sei.c
+++ b/libavcodec/hevc_sei.c
@@ -146,6 +146,83 @@ static int decode_pic_timing(HEVCContext *s)
 return 1;
 }
 
+static int decode_registered_user_data_closed_caption(HEVCContext *s, int size)
+{
+   int flag;
+   int user_data_type_code;
+   int cc_count;
+
+   GetBitContext *gb = >HEVClc->gb;
+
+   if (size < 3)
+   return AVERROR(EINVAL);
+
+   user_data_type_code = get_bits(gb, 8);
+   if (user_data_type_code == 0x3) {
+   skip_bits(gb, 1); // reserved
+
+   flag = get_bits(gb, 1); // process_cc_data_flag
+   if (flag) {
+   skip_bits(gb, 1);
+   cc_count = get_bits(gb, 5);
+   skip_bits(gb, 8); // reserved
+   size -= 2;
+
+   if (cc_count && size >= cc_count * 3) {
+   if (s->a53_caption)
+   av_freep(>a53_caption);
+   s->a53_caption_size = cc_count * 3;
+
+   s->a53_caption = av_malloc(s->a53_caption_size);
+
+   int i;
+   for (i = 0; i < s->a53_caption_size; i++) {
+   s->a53_caption[i++] = get_bits(gb, 8);
+   }
+   skip_bits(gb, 8); // marker_bits
+   }
+   }
+   } else {
+   int i;
+   for (i = 0; i < size - 1; i++)
+   skip_bits(gb, 8);
+   }
+
+   return 0;
+}
+
+static int decode_nal_sei_user_data_registered_itu_t_t35(HEVCContext *s, int 
size)
+{
+uint32_t country_code;
+uint32_t user_identifier;
+
+GetBitContext *gb = >HEVClc->gb;
+
+if (size < 7)
+return AVERROR(EINVAL);
+size -= 7;
+
+country_code = get_bits(gb, 8);
+if (country_code == 0xFF) {
+skip_bits(gb, 8);
+size--;
+}
+
+skip_bits(gb, 8);
+skip_bits(gb, 8);
+
+user_identifier = get_bits_long(gb, 32);
+
+switch (user_identifier) {
+case MKBETAG('G', 'A', '9', '4'):
+return decode_registered_user_data_closed_caption(s, size);
+default:
+skip_bits(gb, size * 8);
+break;
+}
+return 0;
+}
+
 static int active_parameter_sets(HEVCContext *s)
 {
 GetBitContext *gb = >HEVClc->gb;
@@ -198,6 +275,8 @@ static int decode_nal_sei_prefix(HEVCContext *s, int type, 
int size)
 active_parameter_sets(s);
 av_log(s->avctx, AV_LOG_DEBUG, "Skipped PREFIX SEI %d\n", type);
 return 0;
+case SEI_TYPE_USER_DATA_REGISTERED_ITU_T_T35:
+return decode_nal_sei_user_data_registered_itu_t_t35(s, size);
 default:
 av_log(s->avctx, AV_LOG_DEBUG, "Skipped PREFIX SEI %d\n", type);
 skip_bits_long(gb, 8 * size);
-- 
2.6.2

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