Re: [FFmpeg-devel] [PATCH] avfilter/signature: fix integer rounding cast precedence

2021-08-26 Thread Jai Luthra
On Fri, Aug 20, 2021, at 4:24 PM, Jai Luthra wrote:
> Co-authored-by: Oscar 
> Signed-off-by: Jai Luthra 
> ---
>  libavfilter/signature_lookup.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/libavfilter/signature_lookup.c 
> b/libavfilter/signature_lookup.c
> index 977f898049..86dd0c6675 100644
> --- a/libavfilter/signature_lookup.c
> +++ b/libavfilter/signature_lookup.c
> @@ -244,9 +244,9 @@ static MatchingInfo* 
> get_matching_parameters(AVFilterContext *ctx, SignatureCont
>  if (pairs[i].b[j] != pairs[k].b[l]) {
>  /* linear regression */
>  m = (pairs[k].b_pos[l]-pairs[i].b_pos[j]) / 
> (k-i); /* good value between 0.0 - 2.0 */
> -framerate = (int) m*30 + 0.5; /* round up to 0 
> - 60 */
> +framerate = (int) (m*30 + 0.5); /* round up to 
> 0 - 60 */
>  if (framerate>0 && framerate <= MAX_FRAMERATE) 
> {
> -offset = pairs[i].b_pos[j] - ((int) m*i + 
> 0.5); /* only second part has to be rounded up */
> +offset = pairs[i].b_pos[j] - ((int) (m*i + 
> 0.5)); /* only second part has to be rounded up */
>  if (offset > -HOUGH_MAX_OFFSET && offset < 
> HOUGH_MAX_OFFSET) {
>  if (pairs[i].dist < pairs[k].dist) {
>  if (pairs[i].dist < 
> hspace[framerate-1][offset+HOUGH_MAX_OFFSET].dist) {
> -- 
> 2.32.0
> 

Will push in 24h, if no objections.
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH] avfilter/signature: fix integer rounding cast precedence

2021-08-20 Thread Jai Luthra
Co-authored-by: Oscar 
Signed-off-by: Jai Luthra 
---
 libavfilter/signature_lookup.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libavfilter/signature_lookup.c b/libavfilter/signature_lookup.c
index 977f898049..86dd0c6675 100644
--- a/libavfilter/signature_lookup.c
+++ b/libavfilter/signature_lookup.c
@@ -244,9 +244,9 @@ static MatchingInfo* 
get_matching_parameters(AVFilterContext *ctx, SignatureCont
 if (pairs[i].b[j] != pairs[k].b[l]) {
 /* linear regression */
 m = (pairs[k].b_pos[l]-pairs[i].b_pos[j]) / (k-i); /* 
good value between 0.0 - 2.0 */
-framerate = (int) m*30 + 0.5; /* round up to 0 - 60 */
+framerate = (int) (m*30 + 0.5); /* round up to 0 - 60 
*/
 if (framerate>0 && framerate <= MAX_FRAMERATE) {
-offset = pairs[i].b_pos[j] - ((int) m*i + 0.5); /* 
only second part has to be rounded up */
+offset = pairs[i].b_pos[j] - ((int) (m*i + 0.5)); 
/* only second part has to be rounded up */
 if (offset > -HOUGH_MAX_OFFSET && offset < 
HOUGH_MAX_OFFSET) {
 if (pairs[i].dist < pairs[k].dist) {
 if (pairs[i].dist < 
hspace[framerate-1][offset+HOUGH_MAX_OFFSET].dist) {
-- 
2.32.0

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

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


Re: [FFmpeg-devel] [PATCH] lavfi/signature: fix always true expression

2021-07-24 Thread Jai Luthra

On Mon, May 24, 2021 at 04:00:24AM +0300, Valerii Zapodovnikov wrote:

Otherwise since "==" has higher precedence, mode is never checked.
---
libavfilter/signature_lookup.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libavfilter/signature_lookup.c b/libavfilter/signature_lookup.c
index 272c717c77..85e879d224 100644
--- a/libavfilter/signature_lookup.c
+++ b/libavfilter/signature_lookup.c
@@ -491,7 +491,7 @@ static MatchingInfo evaluate_parameters(AVFilterContext 
*ctx, SignatureContext *
meandist = (double) goodfcount / (double) distsum;

if (meandist < minmeandist ||
-status == STATUS_END_REACHED | STATUS_BEGIN_REACHED ||
+status == (STATUS_END_REACHED | STATUS_BEGIN_REACHED) ||
mode == MODE_FAST){
minmeandist = meandist;
/* bestcandidate in this iteration */


will apply thx!


signature.asc
Description: PGP signature
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


Re: [FFmpeg-devel] [PATCH] avfilter/vf_signature: Initialize all houghspace elements

2021-07-19 Thread Jai Luthra

Planning to push it in 24h - if there are no objections.
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


Re: [FFmpeg-devel] [PATCH v2] avcodec/nvenc: fix flushing for encoder-reuse

2021-07-16 Thread Jai Luthra
On Fri, Jul 16, 2021, at 10:06 PM, Timo Rothenpieler wrote:

-- snip --

> Can you explain the logic this follows some more? I'm quite confused 
> what exactly changed, and how it broke this.
> How do you trigger a flush, if calling flush does nothing?

Since https://github.com/ffmpeg/ffmpeg/commit/3ea7057677 it was possible to 
flush nvenc buffers without sending a NULL frame like:

// trigger ff_nvenc_encode_flush which will send a NULL frame internally
// this doesn't set avctx->internal->draining
avcodec_flush_buffers(encoder) 

// get remaining packets out of the buffer
while ... {
avcodec_receive_packet(encoder, )
}

// whenever next segment comes in, reuse encoder without closing & re-opening
avcodec_send_frame(encoder, frame)

But after the recent API changes [1] if someone tries to fetch packets after 
calling avcodec_flush_buffers() they won't receive any and hit EAGAIN.

As the user ran out of frames to encode, no frame is present at 
avctx->internal->buffer_frame - and avctx->internal->draining is unset because 
the user didn't want to send a NULL frame. So ff_encode_get_frame returns 
EAGAIN, which is what the user gets without these changes:

> > @@ -2384,8 +2390,11 @@ int ff_nvenc_receive_packet(AVCodecContext *avctx, 
> > AVPacket *pkt)
> >   
> >   if (!frame->buf[0]) {
> >   res = ff_encode_get_frame(avctx, frame);
> > -if (res < 0 && res != AVERROR_EOF)
> > +if (res == AVERROR_EOF || (ctx->encoder_flushing && res == 
> > AVERROR(EAGAIN))) {
> > +// flushing mode, continue to send packets
> > +} else if (res < 0) {
> >   return res;
> > +}
> >   }



> >   
> >   av_cold void ff_nvenc_encode_flush(AVCodecContext *avctx)
> >   {
> > -NvencContext *ctx = avctx->priv_data;
> > -
> >   nvenc_send_frame(avctx, NULL);
> > -av_fifo_reset(ctx->timestamp_list);
> >   }
> 
> Is it really correct for this to do absolutely nothing now?

It's still sending the NULL frame internally - which will mark encoder_flushing 
as 1 here:

> > @@ -2335,6 +2340,7 @@ static int nvenc_send_frame(AVCodecContext *avctx, 
> > const AVFrame *frame)
> >   nvenc_codec_specific_pic_params(avctx, _params, 
> > ctx->sei_data, sei_count);
> >   } else {
> >   pic_params.encodePicFlags = NV_ENC_PIC_FLAG_EOS;
> > +ctx->encoder_flushing = 1;

We don't wanna cleanup ctx->timestamp_list until the user has retrieved all 
packets from the buffer after triggering a flush.

[1]: 
https://github.com/ffmpeg/ffmpeg/commit/827d6fe73d#diff-ba8b555333cbe9c4d768147d8a7abb152281257770aa314cc057a31f43460fec
 
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH v2] avcodec/nvenc: fix flushing for encoder-reuse

2021-07-16 Thread Jai Luthra
Recent encode API restructure (827d6fe73d) removed some state - which broke
the API for flushing without closing the encoder.

This functionality was originally added in 3ea7057677 and is useful for
segmented video, where we don't want to do expensive re-init of HW sessions
for every segment.
---
v2: Forgot to rebase off master in v1

 libavcodec/nvenc.c | 16 +++-
 libavcodec/nvenc.h |  2 ++
 2 files changed, 13 insertions(+), 5 deletions(-)

diff --git a/libavcodec/nvenc.c b/libavcodec/nvenc.c
index ee046b9cef..ee0beb4795 100644
--- a/libavcodec/nvenc.c
+++ b/libavcodec/nvenc.c
@@ -2281,6 +2281,11 @@ static int nvenc_send_frame(AVCodecContext *avctx, const 
AVFrame *frame)
 return AVERROR(EINVAL);
 
 if (frame && frame->buf[0]) {
+if (ctx->encoder_flushing) {
+ctx->encoder_flushing = 0;
+av_fifo_reset(ctx->timestamp_list);
+}
+
 in_surf = get_free_frame(ctx);
 if (!in_surf)
 return AVERROR(EAGAIN);
@@ -2335,6 +2340,7 @@ static int nvenc_send_frame(AVCodecContext *avctx, const 
AVFrame *frame)
 nvenc_codec_specific_pic_params(avctx, _params, ctx->sei_data, 
sei_count);
 } else {
 pic_params.encodePicFlags = NV_ENC_PIC_FLAG_EOS;
+ctx->encoder_flushing = 1;
 }
 
 res = nvenc_push_context(avctx);
@@ -2384,8 +2390,11 @@ int ff_nvenc_receive_packet(AVCodecContext *avctx, 
AVPacket *pkt)
 
 if (!frame->buf[0]) {
 res = ff_encode_get_frame(avctx, frame);
-if (res < 0 && res != AVERROR_EOF)
+if (res == AVERROR_EOF || (ctx->encoder_flushing && res == 
AVERROR(EAGAIN))) {
+// flushing mode, continue to send packets
+} else if (res < 0) {
 return res;
+}
 }
 
 res = nvenc_send_frame(avctx, frame);
@@ -2395,7 +2404,7 @@ int ff_nvenc_receive_packet(AVCodecContext *avctx, 
AVPacket *pkt)
 } else
 av_frame_unref(frame);
 
-if (output_ready(avctx, avctx->internal->draining)) {
+if (output_ready(avctx, ctx->encoder_flushing)) {
 av_fifo_generic_read(ctx->output_surface_ready_queue, _out_surf, 
sizeof(tmp_out_surf), NULL);
 
 res = nvenc_push_context(avctx);
@@ -2423,8 +2432,5 @@ int ff_nvenc_receive_packet(AVCodecContext *avctx, 
AVPacket *pkt)
 
 av_cold void ff_nvenc_encode_flush(AVCodecContext *avctx)
 {
-NvencContext *ctx = avctx->priv_data;
-
 nvenc_send_frame(avctx, NULL);
-av_fifo_reset(ctx->timestamp_list);
 }
diff --git a/libavcodec/nvenc.h b/libavcodec/nvenc.h
index 85d3a33601..6af3aaf0ce 100644
--- a/libavcodec/nvenc.h
+++ b/libavcodec/nvenc.h
@@ -169,6 +169,8 @@ typedef struct NvencContext
 NV_ENC_SEI_PAYLOAD *sei_data;
 int sei_data_size;
 
+int encoder_flushing;
+
 struct {
 void *ptr;
 int ptr_index;
-- 
2.32.0

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

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH] avcodec/nvenc: fix flushing for encoder-reuse

2021-07-16 Thread Jai Luthra
Recent encode API restructure (827d6fe73d) removed some state - which broke 
the API for flushing without closing the encoder.

This functionality was originally added in 3ea7057677 and is useful for 
segmented video, where we don't want to do expensive re-init of HW sessions 
for every segment.

---
 libavcodec/nvenc.c | 16 +++-
 libavcodec/nvenc.h |  2 ++
 2 files changed, 13 insertions(+), 5 deletions(-)

diff --git a/libavcodec/nvenc.c b/libavcodec/nvenc.c
index dddee8cac1..8eeb955b59 100644
--- a/libavcodec/nvenc.c
+++ b/libavcodec/nvenc.c
@@ -2177,6 +2177,11 @@ static int nvenc_send_frame(AVCodecContext *avctx, const 
AVFrame *frame)
 return AVERROR(EINVAL);
 
 if (frame && frame->buf[0]) {
+if (ctx->encoder_flushing) {
+ctx->encoder_flushing = 0;
+av_fifo_reset(ctx->timestamp_list);
+}
+
 in_surf = get_free_frame(ctx);
 if (!in_surf)
 return AVERROR(EAGAIN);
@@ -2256,6 +2261,7 @@ static int nvenc_send_frame(AVCodecContext *avctx, const 
AVFrame *frame)
 nvenc_codec_specific_pic_params(avctx, _params, sei_data, 
sei_count);
 } else {
 pic_params.encodePicFlags = NV_ENC_PIC_FLAG_EOS;
+ctx->encoder_flushing = 1;
 }
 
 res = nvenc_push_context(avctx);
@@ -2305,8 +2311,11 @@ int ff_nvenc_receive_packet(AVCodecContext *avctx, 
AVPacket *pkt)
 
 if (!frame->buf[0]) {
 res = ff_encode_get_frame(avctx, frame);
-if (res < 0 && res != AVERROR_EOF)
+if (res == AVERROR_EOF || (ctx->encoder_flushing && res == 
AVERROR(EAGAIN))) {
+// flushing mode, continue to send packets
+} else if (res < 0) {
 return res;
+}
 }
 
 res = nvenc_send_frame(avctx, frame);
@@ -2316,7 +2325,7 @@ int ff_nvenc_receive_packet(AVCodecContext *avctx, 
AVPacket *pkt)
 } else
 av_frame_unref(frame);
 
-if (output_ready(avctx, avctx->internal->draining)) {
+if (output_ready(avctx, ctx->encoder_flushing)) {
 av_fifo_generic_read(ctx->output_surface_ready_queue, _out_surf, 
sizeof(tmp_out_surf), NULL);
 
 res = nvenc_push_context(avctx);
@@ -2344,8 +2353,5 @@ int ff_nvenc_receive_packet(AVCodecContext *avctx, 
AVPacket *pkt)
 
 av_cold void ff_nvenc_encode_flush(AVCodecContext *avctx)
 {
-NvencContext *ctx = avctx->priv_data;
-
 nvenc_send_frame(avctx, NULL);
-av_fifo_reset(ctx->timestamp_list);
 }
diff --git a/libavcodec/nvenc.h b/libavcodec/nvenc.h
index fefc5f7f0b..be8194424e 100644
--- a/libavcodec/nvenc.h
+++ b/libavcodec/nvenc.h
@@ -166,6 +166,8 @@ typedef struct NvencContext
 AVFifoBuffer *output_surface_ready_queue;
 AVFifoBuffer *timestamp_list;
 
+int encoder_flushing;
+
 struct {
 void *ptr;
 int ptr_index;
-- 
2.32.0

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

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH] avfilter/vf_signature: Initialize all houghspace elements

2021-07-13 Thread Jai Luthra
Co-authored-by: Oscar 
---
The uninitialized score & dist values are used a few lines below this, leading 
to inconsistent mpeg7 matches.
Original PR here: https://github.com/livepeer/FFmpeg/pull/4

 libavfilter/signature_lookup.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libavfilter/signature_lookup.c b/libavfilter/signature_lookup.c
index 272c717c77..f1d378237a 100644
--- a/libavfilter/signature_lookup.c
+++ b/libavfilter/signature_lookup.c
@@ -200,7 +200,7 @@ static MatchingInfo* 
get_matching_parameters(AVFilterContext *ctx, SignatureCont
 /* initialize houghspace */
 for (i = 0; i < MAX_FRAMERATE; i++) {
 hspace[i] = av_malloc_array(2 * HOUGH_MAX_OFFSET + 1, 
sizeof(hspace_elem));
-for (j = 0; j < HOUGH_MAX_OFFSET; j++) {
+for (j = 0; j < 2 * HOUGH_MAX_OFFSET + 1; j++) {
 hspace[i][j].score = 0;
 hspace[i][j].dist = 9;
 }
-- 
2.32.0

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

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


Re: [FFmpeg-devel] [PATCH 1/3] avcodec/mlp: Make initializing CRCs thread-safe

2020-11-23 Thread Jai Luthra
LGTM

On Tue, Nov 24, 2020, at 1:29 AM, Andreas Rheinhardt wrote:
> Andreas Rheinhardt:
> > Signed-off-by: Andreas Rheinhardt 
> > ---
> >  libavcodec/mlp.c | 17 ++---
> >  1 file changed, 10 insertions(+), 7 deletions(-)
> > 
> > diff --git a/libavcodec/mlp.c b/libavcodec/mlp.c
> > index ddbab60c4e..74363c3b95 100644
> > --- a/libavcodec/mlp.c
> > +++ b/libavcodec/mlp.c
> > @@ -23,6 +23,7 @@
> >  
> >  #include "libavutil/crc.h"
> >  #include "libavutil/intreadwrite.h"
> > +#include "libavutil/thread.h"
> >  #include "mlp.h"
> >  
> >  const uint8_t ff_mlp_huffman_tables[3][18][2] = {
> > @@ -62,7 +63,6 @@ const uint64_t ff_mlp_channel_layouts[12] = {
> >  AV_CH_LAYOUT_4POINT1, AV_CH_LAYOUT_5POINT1_BACK, 0,
> >  };
> >  
> > -static int crc_init = 0;
> >  #if CONFIG_SMALL
> >  #define CRC_TABLE_SIZE 257
> >  #else
> > @@ -72,14 +72,17 @@ static AVCRC crc_63[CRC_TABLE_SIZE];
> >  static AVCRC crc_1D[CRC_TABLE_SIZE];
> >  static AVCRC crc_2D[CRC_TABLE_SIZE];
> >  
> > +static av_cold void mlp_init_crc(void)
> > +{
> > +av_crc_init(crc_63, 0,  8,   0x63, sizeof(crc_63));
> > +av_crc_init(crc_1D, 0,  8,   0x1D, sizeof(crc_1D));
> > +av_crc_init(crc_2D, 0, 16, 0x002D, sizeof(crc_2D));
> > +}
> > +
> >  av_cold void ff_mlp_init_crc(void)
> >  {
> > -if (!crc_init) {
> > -av_crc_init(crc_63, 0,  8,   0x63, sizeof(crc_63));
> > -av_crc_init(crc_1D, 0,  8,   0x1D, sizeof(crc_1D));
> > -av_crc_init(crc_2D, 0, 16, 0x002D, sizeof(crc_2D));
> > -crc_init = 1;
> > -}
> > +static AVOnce init_static_once = AV_ONCE_INIT;
> > +ff_thread_once(_static_once, mlp_init_crc);
> >  }
> >  
> >  uint16_t ff_mlp_checksum16(const uint8_t *buf, unsigned int buf_size)
> > 
> Will apply this patchset tomorrow unless there are objections.
> 
> - 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] [GSoC] [WIP] [RFC] FLIF Encoder & Decoder Project

2020-05-05 Thread Jai Luthra
Hi Kartik,

On Mon, Mar 30, 2020, at 4:50 AM, Kartik K. Khullar wrote:
> This is my WIP patch for GSoC and I worked on transformations involved 
> in encoding/decoding FLIF images. I have created a module under 
> libavcodec and as guided by my mentors I have tried to use pixel data 
> from AVFrame structs.
> Module covers all the chunks of code for YCoCg Transformation that will 
> be used in final encoder/decoder. Necessary structs and methods have 
> been made as suggested by my mentors. The module compiles/builds 
> successfully.
> Also I have attached a small code 'transformtest.c' which I wrote for 
> testing the implementation of pixel transformation.
> The variable AVFrame::data[] is of type uint8_t* and I was initially 
> unaware of this so I stored the YCoCg values in 'data'. So the negative 
> values which were the output of transformation of RGB -> YCoCg were not 
> stored properly and thats where the output is wrong.

I tested your code, and it is good for an initial attempt (ofc the negative 
values are overflowing the uint8_t range, which is wrong). 

Your understanding of the problem is correct, when we transform an RGB value 
that could lie in (0-255, 0-255, 0-255) it can result in a YCoCg value that 
could be anywhere between (0-255, -255-255, -255-255) and thus not fit within 
AVFrame.data which is uint8_t *

> Just wanted to ask, if I should be using some other structs for storing 
> the YCoCg values and not AVFrame, because AVFrame seems to be the 
> standard struct in FFmpeg where the raw media resides.

The YCoCg doesn't need to go in AVFrame as your testcase (RGB->YCoCg) is the 
encoding phase, which reads RGB values from **AVFrame** and ultimately should 
output binary encoded data (after entropy coding) into **AVPacket**. Sorry if 
this was not clear before.

It is OK if you use a bigger buffer with 16-bits per color value for the 
intermediate transform stages. The only invariant is that original frame will 
have 8-bit RGB values, and final encoder output will be binary data. What the 
encoder uses in the interim to represent pixel values doesn't matter to FFmpeg 
api.

But theoretically you will never use all the 16x16x16 bits with YCoCg, as the 
Co range is conditional on Y, and Cg range conditional on Y & Co. It is 
*crucial* for your project that you thoroughly understand the "new ranges" 
section in the spec [1]

Unlike YCbCr (and other common transforms) which goes from 0-255 to 0-255 (or 
even shorter), YCoCg works differently. If we know that Y value is very low or 
very high, it means color components are roughly equal and thus Co and Cg will 
definitely be in a small range. This is what the animation [2] in the spec is 
about. The Y/Luminance varies from 0-255 and the working range of CoCg is shown 
as the size of the square.

I.e. the transform may take a Co value to -255-255 but that will not happen for 
every value of Y. It will only happen when `origmax4-1 <= Y <= 3*origmax4 - 1`. 
Similar rules apply for Cg.

So your next steps should be:
1. Use uint16_t to store interim pixel values for all transformations (doesn't 
need to be part of AVFrame, is internal structure to decoder)
2. Figure out how to implement the crange functions/api as this will be crucial 
for the MANIAC encoder phase (it needs to know the conditional ranges to 
effectively do entropy coding of the pixel values)

> Attaching some testcases of RGB and its corresponding YCoCg values for 
> testing purposes.
> 
> Thanks
> Kartik K. Khullar

Cheers,
Jai

[1]: https://flif.info/spec.html#_new_ranges
[2]: https://www.youtube.com/watch?v=-v-xoKZBnhI
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

[FFmpeg-devel] [PATCH] lavf/fps: add cmd to force write buf frame

2020-05-02 Thread Jai Luthra
Enables writing buffered frames to the outsink using send command api.

This is useful when a lavf user wants to fetch buffered frames without
closing/reopening the filtergraph again and again.

Signed-off-by: Jai Luthra 
---
 libavfilter/vf_fps.c | 36 +++-
 1 file changed, 27 insertions(+), 9 deletions(-)

diff --git a/libavfilter/vf_fps.c b/libavfilter/vf_fps.c
index cf1e36726a..fa856a8f45 100644
--- a/libavfilter/vf_fps.c
+++ b/libavfilter/vf_fps.c
@@ -326,6 +326,23 @@ static int activate(AVFilterContext *ctx)
 return FFERROR_NOT_READY;
 }
 
+static int process_command(AVFilterContext *ctx, const char *cmd, const char 
*args,
+   char *res, int res_len, int flags)
+{
+FPSContext *s = ctx->priv;
+int ret, again = 0;
+
+if (!strcmp(cmd, "force_write")) {
+AVFilterLink *outlink = ctx->outputs[0];
+ret = write_frame(ctx, s, outlink, );
+if (again)
+ff_filter_set_ready(ctx, 100);
+} else
+ret = AVERROR(ENOSYS);
+
+return ret;
+}
+
 static const AVFilterPad avfilter_vf_fps_inputs[] = {
 {
 .name = "default",
@@ -344,13 +361,14 @@ static const AVFilterPad avfilter_vf_fps_outputs[] = {
 };
 
 AVFilter ff_vf_fps = {
-.name= "fps",
-.description = NULL_IF_CONFIG_SMALL("Force constant framerate."),
-.init= init,
-.uninit  = uninit,
-.priv_size   = sizeof(FPSContext),
-.priv_class  = _class,
-.activate= activate,
-.inputs  = avfilter_vf_fps_inputs,
-.outputs = avfilter_vf_fps_outputs,
+.name= "fps",
+.description = NULL_IF_CONFIG_SMALL("Force constant framerate."),
+.init= init,
+.uninit  = uninit,
+.priv_size   = sizeof(FPSContext),
+.priv_class  = _class,
+.activate= activate,
+.inputs  = avfilter_vf_fps_inputs,
+.outputs = avfilter_vf_fps_outputs,
+.process_command = process_command,
 };
-- 
2.26.2

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

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

Re: [FFmpeg-devel] [PATCH] FLIF16 GSOC Project Range Transformation YCoCg

2020-03-21 Thread Jai Luthra

Hi Kartik,

Please mark the patch as [WIP] or [RFC] if you are not sending it for a merge 
review. You may also mark it as [GSoC].


You've done a good job of reading the spec and turning the pseudocode there to 
a method, but I'm afraid it is not enough.


I would suggest you run the reference codec's encoder (and add log statements 
wherever you feel like in the transform related modules) to see how range and 
crange work.


Then try to create test cases for the module you're writing for FFmpeg, i.e. 
pass same values of crange/range etc. and try to see if it behaves similar to 
what the reference decoder would do.


Share your patch with the testcases as well, even if you have a main() 
function and it is not suitable for FFmpeg master just yet.


On Wed, Mar 18, 2020 at 10:56:54AM +0530, Kartik wrote:

From: Kartik K. Khullar

---
FFmpeg/libavcodec/flif16transform.c | 53 +
1 file changed, 53 insertions(+)

diff --git a/FFmpeg/libavcodec/flif16transform.c 
b/FFmpeg/libavcodec/flif16transform.c
index e69de29..febf5e9 100644
--- a/FFmpeg/libavcodec/flif16transform.c
+++ b/FFmpeg/libavcodec/flif16transform.c
@@ -0,0 +1,53 @@
+#include 
+#include 
+
+//array of 2 elements is used as parameter because it represents min, max pair.
+void TransformYCoCg(int16_t *range[2], int16_t *crange[2], int16_t yval, 
int16_t coval){   


What are yval and coval here? Who defines them and calls this method?

I see they are defined in the spec, but take a look at the reference codec to 
figure out what they are and how they work.



+   int max_temp;
+   if (range[1][0] > range[1][1]){
+   if (range[1][0] > range[1][2]){
+   max_temp = range[1][0];
+   }
+   else{
+   max_temp = range[1][2];
+   }
+   }
+   else{
+   max_temp  = range[1][1];
+   }
+   int origmax4 = max_temp / 4 + 1;
+   int newmax = 4*origmax4 - 1;
+   
+   //Updating color ranges
+   range[0][0] = 0;//first channel minimum
+   range[1][0] = newmax;   //first channek maximum
+   range[0][1] = -newmax;  //second channel minimum
+   range[1][1] = newmax;   //second channel maximum
+   range[0][2] = -newmax;  //third channel minimum
+   range[1][2] = newmax;   //third channel maximum
+   
+   //Updating conditional range values
+   crange[0][0] = range[0][0];
+   crange[1][0] = range[1][0];
+   
+   if (yval < origmax4 - 1){
+   crange[0][1] = -3 + 4*yval;
+   crange[1][1] = 3 + 4*yval;
+   crange[0][2] = -2 - 2*yval;
+   crange[1][2] = 1 + 2 * yval - 2 * (abs(coval)/2);
+   }
+   else if (yval > 3*origmax4 - 1){
+   crange[0][1] = 4*(yval - newmax);
+   crange[1][1] = 4*(newmax - yval);
+   crange[0][2] = -2*(newmax - yval) + 2 * ((abs(coval)+1)/2);
+   crange[1][2] = 2*(newmax - yval);
+   }
+   else{   
+   crange[0][1] = -newmax;
+   crange[1][1] = newmax;
+   crange[0][2] = (((2*newmax - 2*yval - 2*abs(coval) + 1) < (2 * 
yval + 1)) ?
+   (2*newmax - 2*yval - 2*abs(coval) + 1) : (2 * yval + 1)) / 2;
+   crange[1][2] = (2*(yval - newmax)) < (-2*yval - 1 + 
2*(abs(coval)/2)) ?
+   (2*(yval - newmax)) : (-2*yval - 1 + 2*(abs(coval)/2));
+   }
+}


Probably as all transformation passses (like YCoCg here) change the range and 
crange, it would be better to create a context struct and define the ranges 
there. And pass that struct's instance as an argument for each transformation 
pass.


Cheers,
Jai
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

Re: [FFmpeg-devel] [PATCH] FLIF16 GSOC Project - Added RGB to YCoCg macros

2020-03-21 Thread Jai Luthra
Please mark the patch as [WIP] or [RFC] if you are not sending it for a merge 
review.


On Wed, Mar 18, 2020 at 11:01:22AM +0530, Kartik wrote:

From: Kartik K. Khullar

---
FFmpeg/libavutil/colorspace.h | 11 +++
1 file changed, 11 insertions(+)

diff --git a/FFmpeg/libavutil/colorspace.h b/FFmpeg/libavutil/colorspace.h
index ef6f610..bf53afe 100644
--- a/FFmpeg/libavutil/colorspace.h
+++ b/FFmpeg/libavutil/colorspace.h
@@ -94,6 +94,17 @@ static inline int C_JPEG_TO_CCIR(int y) {
return y;
}

+#define RGB_TO_YCoCg(R, G, B, Y, Co, Cg){\
+   Y = (((R+B)>>1) + G)>>1;\
+Co = R - B;\
+Cg = G - ((R+B)>>1);\
+}


You don't need to take Y,Co,Cg as inputs to the macro, look at other similar 
macros.


I would also suggest defining different macros for different output channels 
as it does not assume that Y,Co,Cg will be variables defined in the caller's 
context. Take a look at RGB_TO_Y/U/V_JPEG etc.



+
+#define YCoCg_TO_RGB(R, G, B, Y, Co, Cg){\
+   Y = (((R+B)>>1) + G)>>1;\
+Co = R - B;\
+Cg = G - ((R+B)>>1);\
+}


Only the name is inverse here, it still does the forward transform.



#define RGB_TO_Y_CCIR(r, g, b) \
((FIX(0.29900*219.0/255.0) * (r) + FIX(0.58700*219.0/255.0) * (g) + \
--
2.20.1.windows.1


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

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

Re: [FFmpeg-devel] [PATCH] JPEG-XL : Image Format Parser

2020-03-18 Thread Jai Luthra

Hi Varun,

Set [RFC]/[WIP]/[GSOC] and other subject labels for patches that are not 
intended for merge review. From your first email it seems like your mailer 
mangled it. You can edit the .patch file before sending it via git send-email.


On Mon, Mar 16, 2020 at 12:11:54AM +0530, Varun Gupta wrote:

[...]
+
+typedef struct JPEGXLParseContext {
+ParseContext pc;
+int state;
+int index;  // keeps track of number of bits read from the media file
+SizeHeader size;
+PreviewHeader preview;
+ImageMetadata metadata;
+AnimationHeader animation;
+} JPEGXLParseContext;


Most of the decoding specific headers should be read in the decoder itself. 
The parser should only find the end of frames, and decoder can initalize other 
parameters from first packet (which would be header + frame) and use same 
initialized contexts for the subsequent frame packets. Take a look at other 
video and image parsers.


If you think that it won't be possible to find frame ends without reading all 
the headers then that is a different case. Even then you need to make sure 
your parameters reach the decoder module via AVCodecContext->priv_data.


But it is good that you read the spec and figured out the bitstream 
organization.



+
+static unsigned int bits_offset_enum(GetBitContext gb, int n, int offset) {
+unsigned int read_n_bits = get_bits(, n);
+return read_n_bits + offset;
+}
+
+// TODO -> add checks for buffer size overflow in between and ill formed checks
+static int jpegxl_find_frame_end(JPEGXLParseContext *context, const uint8_t 
*buf,
+ int buf_size) {
+int index, next = END_NOT_FOUND;
+GetBitContext gb;
+init_get_bits(, buf, buf_size*8);


init_get_bits8 can be used here as your buf_size is in bytes.


+for (index = 0; index < buf_size*8; ) {
+if (!context->state) {
+if (get_bits(, 8) == JPEG_XL_SIG_FF) {
+context->state = JPEGXL_SIG;


Any particular reason for choosing state as type int and not the enum type it 
is being set to?


You can add a state called JPEGXL_UNDEFINED=0 if you are using int just to 
handle that case



+} else {
+// TODO -> Bitstream is ill formed
+}
+index += 8;


GetBitContext maintains an internal index as well, look into how you can use 
it for your case.



+context->index += 8;
+} else if (context->state == JPEGXL_SIG) {
+if (get_bits(, 8) == JPEG_XL_SIG_TYPE) {
+context->state = JPEGXL_SIZE_HEADER;
+} else {
+// TODO -> Bitstream is ill formed
+}
+index +=8;
+context->index += 8;
+} else if (context->state == JPEGXL_SIZE_HEADER) {
+// default values
+context->size.ysize_div8_minus_1 = 0;
+context->size.ysize_minus_1 = 0;
+context->size.xsize_div8_minus_1 = 0;
+context->size.xsize_minus_1 = 0;


To simplify code you can 0 initialize all structs at start by setting context 
struct to 0. Then you only need to change the non-zero init values.



+
+unsigned int small = get_bits(, 1);


I do not think this will compile with FFmpeg which is C89 standard. Declare 
all variables at top of block. Same with your usage of loop variables, define 
them beforehand.



+index++;
+context->index++;
+if (small) {
+context->size.ysize_div8_minus_1 = get_bits(, 5);
+index += 5;
+context->index += 5;
+} else {
+unsigned int input = get_bits(, 2); // U32() first reads 2 
bits
+index += 2;
+context->index += 2;
+if (input == 0) {   // d0 = Bits(9)
+context->size.ysize_minus_1 = get_bits(, 9);
+index += 9;
+context->index += 9;
+} else if (input == 1) {   // d1 = Bits(13)
+context->size.ysize_minus_1 = get_bits(, 17);
+index += 13;
+context->index += 13;
+} else if (input == 2) {   // d2 = Bits(18)
+context->size.ysize_minus_1 = get_bits_long(, 18);
+index += 18;
+context->index += 18;
+} else {   // d3 = Bits(30)
+context->size.ysize_minus_1 = get_bits_long(, 30);
+index += 30;
+context->index += 30;
+}
+}


you could simplify this a lot by setting a temporary variable to hold the read 
bit size n using a switch case, and then read n bits into the ysize_minus_1. 


similar simplifications can be done at a lot of places.


+unsigned int ratio = get_bits(, 3);
+index += 3;
+context->index += 3;
+if (ratio == 0) {
+if (small) {

Re: [FFmpeg-devel] [PATCH V3] [RFC] GSoC: FLIF16 Image format parser

2020-03-14 Thread Jai Luthra

Hi Anamitra,

Good progres on the parser, I tested it on the samples you provided, lgtm. 
Comments inline.


On Fri, Mar 06, 2020 at 06:10:04PM +, Anamitra Ghorui wrote:

The parser has been tested and is able to correctly identify the start
of the compressed bitstream. The patch has a set of printf statements
which print a "tracing table" of the behaviour. Upon Nicolas George's
suggestion I have made it so that the varints are read into a uint64_t.
Hence the varints are limited in the range 0 to 2^64 - 1.
The test cases are as follows:
1. 1x1 png image (a.flif)
2. 1x1 png image with dummy EXIF data (a1.flif)
3. 2x2 png image (b.flif)
4. 300x200 png image (d.flif)
5. 10x10 gif image, 2 frames (f.flif)
These have been provided as an attachment.
The way I have used AVERROR in the parser may be wrong.

The testing code has been adapted from:
https://ffmpeg.org/doxygen/trunk/decode_video_8c-example.html
The concerned part is (available as attachment):
...
while (!feof(f)) {
   /* read raw data from the input file */
   data_size = fread(inbuf, 1, INBUF_SIZE, f);
   if (!data_size)
   break;
   /* use the parser to split the data into frames */
   data = inbuf;
   while (data_size > 0) {
   ret = av_parser_parse2(parser, c, >data, >size,
  data, data_size, AV_NOPTS_VALUE, 
AV_NOPTS_VALUE, 0);
   if (ret < 0) {
   fprintf(stderr, "Error while parsing\n");
   exit(1);
   }
   data  += ret;
   data_size -= ret;
   if (pkt->size > 0)
   {
   printf("Reached bitstream at 0x%x (%dd)\n", pkt->size,
  pkt->size);
   goto end;
   }
   }
   }
   end:
...



Yes afaics parser does not generally return errors. Usually the parser splits 
the frames out if it is able to, and the decoder verifies if something is 
wrong within the packet bitstream.


I am not certain how this should be handled here as you plan to do entropy 
decoding within the parser.


Parser's ret value being < 0 usually implies that frame start was in previous 
packet, but look around other parsers and ask in #ffmpeg-devel if your 
approach is feasible.



Now comes the part of decompressing the bitstream and finding the bounds
of the data. I haven't yet properly gone through the reference
implementation due to a lack of time (I will have now), but I'm thinking
of defining a few functions:

int ff_flif16_read_rac(uint8_t *buf, unsigned int buf_size,
unsinged int offset,
FLIF16ChanceTable chance);
int ff_flif16_read_uni_int(int min, int max);
int ff_flif16_read_nz_int(int min, int max,  FLIF16ChanceTable context);
int ff_flif16_read_gnz_int(int min, int max, FLIF16ChanceTable context);
(...)


I haven't heard from the other applicant who was working on the entropy 
decoding task, so I would suggest you can go ahead with implementing this. I 
think you may be able to use/modify the existing range coder ffmpeg module.




The decoder itself will not handle decompressing or decoding the
bitstream, rather we will alter the buffer to add in the decompressed
bitstream, then run it through the parser and add it to the AVPacket,
and finally pass it to the decoder. The decoder will then decode all
the frames from that single packet.





+typedef struct FLIF16ParseContext {
+ParseContext pc;
+int state;  ///< The section of the file the parser is in 
currently.
+unsigned int index; ///< An index based on the current state.
+uint8_t iac;///< Interlaced, animated, color palette info


For testing this is good enough, but I think it would be a better idea to have 
separate fields in the context for interlaced/animated/color pallete etc. so 
that you don't need to do bitshifts everywhere you need to use them as done 
below.



+uint8_t varint; ///< Number of varints to process in sequence
+uint64_t width;
+uint64_t height;
+uint64_t frames;
+uint64_t meta;  ///< Size of a meta chunk
+uint64_t count;
+} FLIF16ParseContext;
+
+static int flif16_find_frame(FLIF16ParseContext *f, const uint8_t *buf,
+ int buf_size)
+{
+int next = END_NOT_FOUND;
+int index;
+
+printf("pos\tfindex\tstate\tval\tw\th\tframes\tmeta\tvarintn\n");
+for (index = 0; index < buf_size; index++) {
+printf("%d\t%d\t%d\t0x%x\t0x%lx\t0x%lx\t%lx\t%lx\t%d\n", index,
+   f->index, f->state, buf[index], f->width, f->height, f->frames,
+   f->meta, f->varint);
+if (!f->state) {
+if (!memcmp(flif16_header, buf + index, 4))
+f->state = FLIF16_HEADER;
+++f->index;
+} else if (f->state == FLIF16_HEADER) {
+if (f->index == 3 + 1) { // Interlaced/animated/color palette info
+f->iac = 

Re: [FFmpeg-devel] GSoC: Regarding Parsing and FLIF16 Frame Encoding

2020-02-29 Thread Jai Luthra

Hi Anamitra,

On Sat, Feb 29, 2020 at 04:50:23AM +, Anamitra Ghorui wrote:

Hello,
I have been reading through the parsing API and other things and here's what
I've managed to gather (I will be ignoring overruns in these functions for now).
Please tell me if I am right or wrong:

1. As long as the parse function determines next == END_NOT_FOUND,
  ff_combine_frame will keep increasing the AVParseContext index by buf_size.
  Once next is no longer END_NOT_FOUND, buf_size will be set to index + next.

  The bytes from the input chunks are copied into the buffer of AVParseContext
  during this process.

  while next == END_NOT_FOUND, and the thing being decoded is a video, we
  cannot really determine the end of frame, and hence poutbuf and poutbuf_size
  are set to zero by the function. However, this doesn't really matter for
  still images since they have a single frame.

2. av_parser_parse2 will look for whether poutbuf_size is greater than zero.
  If it is, the next frame start offset will be advanced, and the frame offset
  pointer will be set to the previous value of the next frame offset in
  AVCodecParserContext.

3. In https://ffmpeg.org/doxygen/trunk/decode_video_8c-example.html
  pkt->size will be set to zero as long as a frame has not been returned.
  Hence decode will not be triggered as long as a frame has not been found.


Yes this is all correct. Good work of looking at different parsers to 
understand this.




Now, Regarding FLIF16:
1. The pixels of the image are stored in this format (non interlaced):
(see https://flif.info/spec.html#_part_4_pixel_data)
 ___
| _ |
|| ___ ||
all  ||| _ |||
|||| 
||| f1 | x1 x2 x3 . xw   
|||| 
|| y1 ||_
| c1 ||...|||
||| _ |||
|||| 
||| fn | x1 x2 x3 . xw   
|||| 
||||_
|||   |||
|||___|||
|| ... ||
|| ___ ||
||| _ |||
|||| 
||| f1 | x1 x2 x3 . xw   
|||| 
|| yh ||_
|||   ... |||
||| _ |||
|||| 
||| fn | x1 x2 x3 . xw   
|||| 
||||_
|||   |||
|||___|||
||_||
|   |
|  ...  |
| cn|
|___|

where: ci: color channel
  yi: pixel row
  fi: frame number
  xi: individual pixel


Ah FLIF is a bit wacky. I can see why this might be helpful for decoding 
partial images on-the-fly, but I don't think it will be easy or even possible 
to do with the current AVFrame API.




The frames are not stored in a contiguous manner as observable. How should I be
getting the frame over here? It dosen't seem possible without either putting the
whole pixel data chunk in memory, or allocating space for all the frames at once
and then putting data in them.

I guess what the parser has to do in that case is that it will have to either
return the whole file length as the buffer to the decoder function, or make the
parser manage frames by itself through its own data structures and component
functions.

What should I be doing here?


For now go with the approach of reading all the data into a single AVPacket. 
This does mean that parser isn't splitting frames. We can figure out how to do 
progressive decoding like intended by FLIF later.




2. The FLIF format spec refers to a thing known as the 24 bit RAC. Is it an
  abbreviation for 24 bit RAnge Coding? 
(https://en.wikipedia.org/wiki/Range_encoding)
  What does the "24 bit" mean? Is it the size of each symbol that is processed
  by the range coder?



Yes RAC refers to Range Coding [1]. You can try to match what the reference 
codec does in [2] with the explanation in [1].


"24 

Re: [FFmpeg-devel] [PATCH] [RFC] GSoC: FLIF16 Image format parser

2020-02-27 Thread Jai Luthra

Hi Anamitra,

On Wed, Feb 26, 2020 at 12:26:37PM +0530, Anamitra Ghorui wrote:

This is a buildable "skeleton" of my component (the FLIF16 parser)
i.e. everything is present aside from the logic itself.

***

Hello, I am trying to implement a parser for the FLIF16 file format as
a GSoC 2020 qualification project. So far I think I have managed to
register the parser (alongwith the format) and the basic structure
of the parser code.

I have now reached a point where moving forward is going to be quite
difficult without outside help and references, and so I have a number
of questions regarding the conceptual understanding of FFmpeg:

a. Please tell me if I am right or wrong here:
1. Each audio/video/image file format has a parser for converting the
  file data into a format that can be understood by a decoder.


Yes



2. A Decoder converts a given, recogised encoded data stream into a
  form that can be processed by physical hardware.


Yes. To be exact, decoder turns the encoded data packets to raw frames or 
samples, which can then be transcoded to some other codec or displayed/played.




3. File formats can be independent of what sort of encoding it uses.
  Eg: WebM


Yes a single container format can support diff codecs.



4. The general Audio parsing/decoding process is as follows:
i. Allocate space for a packet of data
   ii. Try to find a hit for the codec of  given data format
  iii. Now, with the codec id, attempt to init a parser
   iv. Allocate a context for the codec
v. Initialize the codec context
   vi. Initialize the codec
  vii. Allocate space for frame data
 viii. Open the imput file
   ix. While file pointer isn't EOF:
   Read data into buffer
   Parse data into a single frame
   Decode the data
x. Flush the file and free stuff.


Yes, there may also be some form of probing taking place, i.e. checking the 
first few packets to find what file format and codec is used. 



5. Every parser has its own parser context extended from the default parser
  context. The byte offsets/positions in the file are kept by the parser
  context.

6. An image can be thought of as a video with a single frame


For some purposes this high level distinction may work. But many image formats 
also support multiple frames and animations like GIF and even FLIF. 



b. In libavcodec/parser.h:

   typedef struct ParseContext{
   ...
   int frame_start_found;
   ...
   } ParseContext;

Is frame_start_found the determined position of the start of the frame
in the data stream?


c. I have been looking at the decoder/encoder/parser of the BMP format
  (which is one of the simplest image formats), the actual decoding work
  (according to me), i.e. Finding the magic numbers, seeing the various
  segments is being done by the decoder function and not the parser.

  The parser function from what I can see from the png_parser and
  bmp_parser, simply manipulates the ParseConstext for appropriate
  values, and does not much else. What is it exactly doing over here?


You are correct. The parser is usally used for video formats, to read and 
iterate over encoded packets/frames in a bitstream. Main decoding part and 
filling contexts for a particular packet is done within the decoder module 
usually.


FLIF does have multiple frames so having a parser is a good idea. But you may 
choose to read the other information through header into the decoder context, 
that is up to you whatever you find better.




If there are any books or articles I should read, please tell me.
---
libavcodec/Makefile|  1 +
libavcodec/avcodec.h   |  1 +
libavcodec/flif16_parser.c | 51 ++
libavcodec/parsers.c   |  1 +
libavformat/img2.c |  1 +
5 files changed, 55 insertions(+)
create mode 100644 libavcodec/flif16_parser.c

diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index 1e894c8049..ce18632d2c 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -1045,6 +1045,7 @@ OBJS-$(CONFIG_DVD_NAV_PARSER)  += dvd_nav_parser.o
OBJS-$(CONFIG_DVDSUB_PARSER)   += dvdsub_parser.o
OBJS-$(CONFIG_FLAC_PARSER) += flac_parser.o flacdata.o flac.o \
  vorbis_data.o
+OBJS-$(CONFIG_FLAC_PARSER) += flif16_parser.o
OBJS-$(CONFIG_G723_1_PARSER)   += g723_1_parser.o
OBJS-$(CONFIG_G729_PARSER) += g729_parser.o
OBJS-$(CONFIG_GIF_PARSER)  += gif_parser.o
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index 978f36d12a..c6b8c6a1eb 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -461,6 +461,7 @@ enum AVCodecID {
AV_CODEC_ID_MVDV,
AV_CODEC_ID_MVHA,
AV_CODEC_ID_CDTOONS,
+AV_CODEC_ID_FLIF16,

/* various PCM "codecs" */
AV_CODEC_ID_FIRST_AUDIO = 0x1, ///< A dummy id pointing at the 
start of audio codecs
diff --git a/libavcodec/flif16_parser.c b/libavcodec/flif16_parser.c
new file mode 100644
index 

Re: [FFmpeg-devel] FLIF Encoder & Decoder Project for GSOC 2020

2020-02-23 Thread Jai Luthra

On Sun, Feb 23, 2020 at 02:54:42PM +0530, Kartik Khullar wrote:

I am 2nd year Computer Engineering Student at TIET, Patiala. I am
interested in FLIF Encoder and Decoder Project. I am informing so as to
prevent clash between other potential applicants. I will be working on its
Qualification Task.


Hey Kartik, thanks for letting us know!

I have previously studied theory and mathematics behind JPEG Compression 
using DCT, also I am good at C/C++ and have worked using git before. Also any 
help from mentor's side will be helpful for me.


DSP knowledge is a great plus. FLIF does not use DCT but uses other lossless 
transformation passes as given in the spec [1].


Pick a couple of the passes and/or other components of FLIF like parsing the 
bitstream for packets/headers or the MANIAC entropy coder. Understand them 
through the spec and the reference codec, and write a module under lavc. 
Decoding part is usually easier to start with, but it is up to you.


Let us know whatever component(s) you pick, and if you have any doubts ask 
away here or on the #ffmpeg-devel IRC.



Thank You.
Kartik K. Khullar


[1]: https://flif.info/spec.html

--
Jai (darkapex)


signature.asc
Description: PGP signature
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

[FFmpeg-devel] [PATCH] avcodec/mlpdec: use get_bits_long for huff lsbs

2020-02-07 Thread Jai Luthra
lsb bits may go beyond 25 bits, so to be safe use get_bits_long

Signed-off-by: Jai Luthra 
---
 libavcodec/mlpdec.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libavcodec/mlpdec.c b/libavcodec/mlpdec.c
index 22a6efd63d..1a2c0f29ac 100644
--- a/libavcodec/mlpdec.c
+++ b/libavcodec/mlpdec.c
@@ -266,7 +266,7 @@ static inline int read_huff_channels(MLPDecodeContext *m, 
GetBitContext *gbp,
 return AVERROR_INVALIDDATA;
 
 if (lsb_bits > 0)
-result = (result << lsb_bits) + get_bits(gbp, lsb_bits);
+result = (result << lsb_bits) + get_bits_long(gbp, lsb_bits);
 
 result  += cp->sign_huff_offset;
 result *= 1 << quant_step_size;
-- 
2.25.0

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

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

Re: [FFmpeg-devel] [PATCH 7/7] mlp: check huff_lsbs only when codebook is used

2020-02-06 Thread Jai Luthra

On Tue, Feb 04, 2020 at 10:24:50PM +0100, Michael Niedermayer wrote:

On Mon, Feb 03, 2020 at 12:33:00AM +0530, Jai Luthra wrote:

When no codebook is used, huff_lsbs can be more than 24 and still decode to
original values once filters are applied.


huff_lsbs can but get_bits() is limited to 25, you need get_bits_long() beyond


I see, thx Michael!

There are two ways to deal with this:

1) Use get_bits_long() where get_bits() is used to read the lsb_bits from the 
bitstream as it is certainly going to be within 32.


2) Limit huff_lsbs to 25 bits even if no codebook.

I tested encoding various samples and it does not go above 25 bits. It hits 25 
in mlpenc because at the matrixing stage L+R channels get added together in a 
single channel, but I am not sure if other encoders would also adhere to that.


(I was previously wrong in assuming that it hits more than 24 at the filtering 
stage, I tested it [1] and it does so after the re-matrixing stage, before any 
FIR filters)


I prefer (1) as it is cleaner. Let me know if that is OK and I'll send a 
patch.


Cheers,
Jai

[1]: 
https://github.com/jailuthra/FFmpeg/commit/04cf7262496cd296be3b3beaf049bdb1887f2d84
with https://lynne.ee/files/sample.flac



thx

[...]
--
Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB

If you think the mosad wants you dead since a long time then you are either
wrong or dead since a long time.

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

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

[FFmpeg-devel] [PATCH v2 6/7] mlpenc: fix -fsanitize=integer errors

2020-02-03 Thread Jai Luthra
Signed-off-by: Jai Luthra 
---
 libavcodec/mlpenc.c | 20 ++--
 1 file changed, 10 insertions(+), 10 deletions(-)

v2: fixes more integer issues

diff --git a/libavcodec/mlpenc.c b/libavcodec/mlpenc.c
index 347a43248c..173cf71956 100644
--- a/libavcodec/mlpenc.c
+++ b/libavcodec/mlpenc.c
@@ -87,11 +87,11 @@ typedef struct {
 } DecodingParams;
 
 typedef struct BestOffset {
-int16_t offset;
+int32_t offset;
 int bitcount;
 int lsb_bits;
-int16_t min;
-int16_t max;
+int32_t min;
+int32_t max;
 } BestOffset;
 
 #define HUFF_OFFSET_MIN(-16384)
@@ -568,7 +568,7 @@ static av_cold int mlp_encode_init(AVCodecContext *avctx)
 }
 ctx->coded_sample_fmt[1] = -1 & 0xf;
 
-ctx->dts = -avctx->frame_size;
+ctx->dts = (uint16_t) (-avctx->frame_size);
 
 ctx->num_channels = avctx->channels + 2; /* +2 noise channels */
 ctx->one_sample_buffer_size = avctx->frame_size
@@ -1249,7 +1249,7 @@ static void input_data_internal(MLPEncodeContext *ctx, 
const uint8_t *samples,
 uint32_t abs_sample;
 int32_t sample;
 
-sample = is24 ? *samples_32++ >> 8 : *samples_16++ * 256U;
+sample = is24 ? *samples_32++ >> 8 : *samples_16++ * 256;
 
 /* TODO Find out if number_sbits can be used for negative 
values. */
 abs_sample = FFABS(sample);
@@ -1589,7 +1589,7 @@ static void no_codebook_bits(MLPEncodeContext *ctx,
  BestOffset *bo)
 {
 DecodingParams *dp = ctx->cur_decoding_params;
-int16_t offset;
+int32_t offset;
 int32_t unsign = 0;
 uint32_t diff;
 int lsb_bits;
@@ -1611,7 +1611,7 @@ static void no_codebook_bits(MLPEncodeContext *ctx,
 
 /* If all samples are the same (lsb_bits == 0), offset must be
  * adjusted because of sign_shift. */
-offset = min + diff / 2 + !!lsb_bits;
+offset = min + (int) (diff / 2) + !!lsb_bits;
 
 bo->offset   = offset;
 bo->lsb_bits = lsb_bits;
@@ -1792,7 +1792,7 @@ static void determine_bits(MLPEncodeContext *ctx)
 #define SAMPLE_MAX(bitdepth) ((1 << (bitdepth - 1)) - 1)
 #define SAMPLE_MIN(bitdepth) (~SAMPLE_MAX(bitdepth))
 
-#define MSB_MASK(bits)  (-(1u << (bits)))
+#define MSB_MASK(bits)  (-(int)(1u << (bits)))
 
 /** Applies the filter to the current samples, and saves the residual back
  *  into the samples buffer. If the filter is too bad and overflows the
@@ -2280,8 +2280,8 @@ static int mlp_encode_frame(AVCodecContext *avctx, 
AVPacket *avpkt,
 
 bytes_written = write_access_unit(ctx, avpkt->data, avpkt->size, 
restart_frame);
 
-ctx->timestamp += ctx->frame_size[ctx->frame_index];
-ctx->dts   += ctx->frame_size[ctx->frame_index];
+ctx->timestamp = (uint16_t) (ctx->timestamp + 
ctx->frame_size[ctx->frame_index]);
+ctx->dts   = (uint16_t) (ctx->dts   + 
ctx->frame_size[ctx->frame_index]);
 
 input_and_return:
 
-- 
2.25.0

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

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

[FFmpeg-devel] [PATCH 6/7] mlpenc: fix -fsanitize=integer errors

2020-02-02 Thread Jai Luthra
Signed-off-by: Jai Luthra 
---
 libavcodec/mlpenc.c | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

 Thanks to Paul for the original pastebin patch

diff --git a/libavcodec/mlpenc.c b/libavcodec/mlpenc.c
index 347a43248c..af04648097 100644
--- a/libavcodec/mlpenc.c
+++ b/libavcodec/mlpenc.c
@@ -87,11 +87,11 @@ typedef struct {
 } DecodingParams;
 
 typedef struct BestOffset {
-int16_t offset;
+int32_t offset;
 int bitcount;
 int lsb_bits;
-int16_t min;
-int16_t max;
+int32_t min;
+int32_t max;
 } BestOffset;
 
 #define HUFF_OFFSET_MIN(-16384)
@@ -1249,7 +1249,7 @@ static void input_data_internal(MLPEncodeContext *ctx, 
const uint8_t *samples,
 uint32_t abs_sample;
 int32_t sample;
 
-sample = is24 ? *samples_32++ >> 8 : *samples_16++ * 256U;
+sample = is24 ? *samples_32++ >> 8 : *samples_16++ * 256;
 
 /* TODO Find out if number_sbits can be used for negative 
values. */
 abs_sample = FFABS(sample);
@@ -1792,7 +1792,7 @@ static void determine_bits(MLPEncodeContext *ctx)
 #define SAMPLE_MAX(bitdepth) ((1 << (bitdepth - 1)) - 1)
 #define SAMPLE_MIN(bitdepth) (~SAMPLE_MAX(bitdepth))
 
-#define MSB_MASK(bits)  (-(1u << (bits)))
+#define MSB_MASK(bits)  (-(int)(1u << (bits)))
 
 /** Applies the filter to the current samples, and saves the residual back
  *  into the samples buffer. If the filter is too bad and overflows the
-- 
2.25.0

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

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

[FFmpeg-devel] [PATCH 7/7] mlp: check huff_lsbs only when codebook is used

2020-02-02 Thread Jai Luthra
When no codebook is used, huff_lsbs can be more than 24 and still decode to 
original values once filters are applied.

Signed-off-by: Jai Luthra 
---
 libavcodec/mlpdec.c | 2 +-
 libavcodec/mlpenc.c | 3 +++
 2 files changed, 4 insertions(+), 1 deletion(-)

Fixes lossless check failures caused with https://lynne.ee/files/sample.flac

diff --git a/libavcodec/mlpdec.c b/libavcodec/mlpdec.c
index 39c40914cd..22a6efd63d 100644
--- a/libavcodec/mlpdec.c
+++ b/libavcodec/mlpdec.c
@@ -829,7 +829,7 @@ static int read_channel_params(MLPDecodeContext *m, 
unsigned int substr,
 cp->codebook  = get_bits(gbp, 2);
 cp->huff_lsbs = get_bits(gbp, 5);
 
-if (cp->huff_lsbs > 24) {
+if (cp->codebook > 0 && cp->huff_lsbs > 24) {
 av_log(m->avctx, AV_LOG_ERROR, "Invalid huff_lsbs.\n");
 cp->huff_lsbs = 0;
 return AVERROR_INVALIDDATA;
diff --git a/libavcodec/mlpenc.c b/libavcodec/mlpenc.c
index af04648097..4e60ffd217 100644
--- a/libavcodec/mlpenc.c
+++ b/libavcodec/mlpenc.c
@@ -987,6 +987,9 @@ static void write_decoding_params(MLPEncodeContext *ctx, 
PutBitContext *pb,
 put_bits(pb, 1, 0);
 }
 }
+if (cp->codebook > 0 && cp->huff_lsbs > 24) {
+av_log(ctx->avctx, AV_LOG_ERROR, "Invalid Huff LSBs\n");
+}
 
 put_bits(pb, 2, cp->codebook );
 put_bits(pb, 5, cp->huff_lsbs);
-- 
2.25.0

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

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

Re: [FFmpeg-devel] [PATCH 3/4] avcodec/mlpdsp: Fix a invalid shift in ff_mlp_rematrix_channel()

2020-02-02 Thread Jai Luthra

On Sun, Feb 02, 2020 at 01:16:38AM +0100, Michael Niedermayer wrote:

Fixes: left shift of negative value -2
Fixes: 
20305/clusterfuzz-testcase-minimized-ffmpeg_AV_CODEC_ID_TRUEHD_fuzzer-5677196618498048

Found-by: continuous fuzzing process 
https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg
Signed-off-by: Michael Niedermayer 
---
libavcodec/mlpdsp.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libavcodec/mlpdsp.c b/libavcodec/mlpdsp.c
index 32a4503b64..12bef3a721 100644
--- a/libavcodec/mlpdsp.c
+++ b/libavcodec/mlpdsp.c
@@ -79,7 +79,7 @@ void ff_mlp_rematrix_channel(int32_t *samples,

if (matrix_noise_shift) {
index &= access_unit_size_pow2 - 1;
-accum += noise_buffer[index] << (matrix_noise_shift + 7);
+accum += noise_buffer[index] * (1 << (matrix_noise_shift + 7));
index += index2;
}

--
2.17.1

___



lgtm.

--
Jai


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".

[FFmpeg-devel] [PATCH 5/5] mlpenc: clean up

2020-01-25 Thread Jai Luthra
Signed-off-by: Jai Luthra 
---

On Fri, Jan 24, 2020 at 02:25:20PM +0100, Paul B Mahol wrote:
> This is not cleanup, this adds new line of code without proper explanation.
My bad, I was testing something and forgot to remove that line. Fixed now.

 libavcodec/mlpenc.c | 23 ++-
 1 file changed, 10 insertions(+), 13 deletions(-)

diff --git a/libavcodec/mlpenc.c b/libavcodec/mlpenc.c
index 0e7a9b7640..347a43248c 100644
--- a/libavcodec/mlpenc.c
+++ b/libavcodec/mlpenc.c
@@ -94,8 +94,8 @@ typedef struct BestOffset {
 int16_t max;
 } BestOffset;
 
-#define HUFF_OFFSET_MIN-16384
-#define HUFF_OFFSET_MAX 16383
+#define HUFF_OFFSET_MIN(-16384)
+#define HUFF_OFFSET_MAX( 16383)
 
 /** Number of possible codebooks (counting "no codebooks") */
 #define NUM_CODEBOOKS   4
@@ -808,7 +808,7 @@ static void write_major_sync(MLPEncodeContext *ctx, uint8_t 
*buf, int buf_size)
 static void write_restart_header(MLPEncodeContext *ctx, PutBitContext *pb)
 {
 RestartHeader *rh = ctx->cur_restart_header;
-int32_t lossless_check = xor_32_to_8(rh->lossless_check_data);
+uint8_t lossless_check = xor_32_to_8(rh->lossless_check_data);
 unsigned int start_count = put_bits_count(pb);
 PutBitContext tmpb;
 uint8_t checksum;
@@ -1017,12 +1017,10 @@ static void write_block_data(MLPEncodeContext *ctx, 
PutBitContext *pb)
 codebook_index  [ch] = cp->codebook  - 1;
 sign_huff_offset[ch] = cp->huff_offset;
 
-sign_shift = lsb_bits[ch] - 1;
+sign_shift = lsb_bits[ch] + (cp->codebook ? 2 - cp->codebook : -1);
 
-if (cp->codebook > 0) {
+if (cp->codebook > 0)
 sign_huff_offset[ch] -= 7 << lsb_bits[ch];
-sign_shift += 3 - cp->codebook;
-}
 
 /* Unsign if needed. */
 if (sign_shift >= 0)
@@ -1032,7 +1030,6 @@ static void write_block_data(MLPEncodeContext *ctx, 
PutBitContext *pb)
 for (i = 0; i < dp->blocksize; i++) {
 for (ch = rh->min_channel; ch <= rh->max_channel; ch++) {
 int32_t sample = *sample_buffer++ >> dp->quant_step_size[ch];
-
 sample -= sign_huff_offset[ch];
 
 if (codebook_index[ch] >= 0) {
@@ -1252,7 +1249,7 @@ static void input_data_internal(MLPEncodeContext *ctx, 
const uint8_t *samples,
 uint32_t abs_sample;
 int32_t sample;
 
-sample = is24 ? *samples_32++ >> 8 : *samples_16++ << 8;
+sample = is24 ? *samples_32++ >> 8 : *samples_16++ * 256U;
 
 /* TODO Find out if number_sbits can be used for negative 
values. */
 abs_sample = FFABS(sample);
@@ -1795,7 +1792,7 @@ static void determine_bits(MLPEncodeContext *ctx)
 #define SAMPLE_MAX(bitdepth) ((1 << (bitdepth - 1)) - 1)
 #define SAMPLE_MIN(bitdepth) (~SAMPLE_MAX(bitdepth))
 
-#define MSB_MASK(bits)  (-1u << bits)
+#define MSB_MASK(bits)  (-(1u << (bits)))
 
 /** Applies the filter to the current samples, and saves the residual back
  *  into the samples buffer. If the filter is too bad and overflows the
@@ -1899,8 +1896,8 @@ static void generate_2_noise_channels(MLPEncodeContext 
*ctx)
 
 for (i = 0; i < ctx->number_of_samples; i++) {
 uint16_t seed_shr7 = seed >> 7;
-*sample_buffer++ = ((int8_t)(seed >> 15)) << rh->noise_shift;
-*sample_buffer++ = ((int8_t) seed_shr7)   << rh->noise_shift;
+*sample_buffer++ = ((int8_t)(seed >> 15)) * (1 << rh->noise_shift);
+*sample_buffer++ = ((int8_t) seed_shr7)   * (1 << rh->noise_shift);
 
 seed = (seed << 16) ^ seed_shr7 ^ (seed_shr7 << 5);
 
@@ -2275,7 +2272,7 @@ static int mlp_encode_frame(AVCodecContext *avctx, 
AVPacket *avpkt,
 if (restart_frame) {
 set_major_params(ctx);
 if (ctx->min_restart_interval != ctx->max_restart_interval)
-process_major_frame(ctx);
+process_major_frame(ctx);
 }
 
 if (ctx->min_restart_interval == ctx->max_restart_interval)
-- 
2.25.0

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

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

[FFmpeg-devel] [PATCH 5/5] mlpenc: clean up

2020-01-24 Thread Jai Luthra
Signed-off-by: Jai Luthra 
---
 libavcodec/mlpenc.c | 30 ++
 1 file changed, 14 insertions(+), 16 deletions(-)

diff --git a/libavcodec/mlpenc.c b/libavcodec/mlpenc.c
index 0e7a9b7640..40872c42fa 100644
--- a/libavcodec/mlpenc.c
+++ b/libavcodec/mlpenc.c
@@ -94,8 +94,8 @@ typedef struct BestOffset {
 int16_t max;
 } BestOffset;
 
-#define HUFF_OFFSET_MIN-16384
-#define HUFF_OFFSET_MAX 16383
+#define HUFF_OFFSET_MIN(-16384)
+#define HUFF_OFFSET_MAX( 16383)
 
 /** Number of possible codebooks (counting "no codebooks") */
 #define NUM_CODEBOOKS   4
@@ -808,7 +808,7 @@ static void write_major_sync(MLPEncodeContext *ctx, uint8_t 
*buf, int buf_size)
 static void write_restart_header(MLPEncodeContext *ctx, PutBitContext *pb)
 {
 RestartHeader *rh = ctx->cur_restart_header;
-int32_t lossless_check = xor_32_to_8(rh->lossless_check_data);
+uint8_t lossless_check = xor_32_to_8(rh->lossless_check_data);
 unsigned int start_count = put_bits_count(pb);
 PutBitContext tmpb;
 uint8_t checksum;
@@ -1017,12 +1017,10 @@ static void write_block_data(MLPEncodeContext *ctx, 
PutBitContext *pb)
 codebook_index  [ch] = cp->codebook  - 1;
 sign_huff_offset[ch] = cp->huff_offset;
 
-sign_shift = lsb_bits[ch] - 1;
+sign_shift = lsb_bits[ch] + (cp->codebook ? 2 - cp->codebook : -1);
 
-if (cp->codebook > 0) {
+if (cp->codebook > 0)
 sign_huff_offset[ch] -= 7 << lsb_bits[ch];
-sign_shift += 3 - cp->codebook;
-}
 
 /* Unsign if needed. */
 if (sign_shift >= 0)
@@ -1032,7 +1030,6 @@ static void write_block_data(MLPEncodeContext *ctx, 
PutBitContext *pb)
 for (i = 0; i < dp->blocksize; i++) {
 for (ch = rh->min_channel; ch <= rh->max_channel; ch++) {
 int32_t sample = *sample_buffer++ >> dp->quant_step_size[ch];
-
 sample -= sign_huff_offset[ch];
 
 if (codebook_index[ch] >= 0) {
@@ -1252,7 +1249,7 @@ static void input_data_internal(MLPEncodeContext *ctx, 
const uint8_t *samples,
 uint32_t abs_sample;
 int32_t sample;
 
-sample = is24 ? *samples_32++ >> 8 : *samples_16++ << 8;
+sample = is24 ? *samples_32++ >> 8 : *samples_16++ * 256U;
 
 /* TODO Find out if number_sbits can be used for negative 
values. */
 abs_sample = FFABS(sample);
@@ -1795,7 +1792,7 @@ static void determine_bits(MLPEncodeContext *ctx)
 #define SAMPLE_MAX(bitdepth) ((1 << (bitdepth - 1)) - 1)
 #define SAMPLE_MIN(bitdepth) (~SAMPLE_MAX(bitdepth))
 
-#define MSB_MASK(bits)  (-1u << bits)
+#define MSB_MASK(bits)  (-(1u << (bits)))
 
 /** Applies the filter to the current samples, and saves the residual back
  *  into the samples buffer. If the filter is too bad and overflows the
@@ -1899,8 +1896,8 @@ static void generate_2_noise_channels(MLPEncodeContext 
*ctx)
 
 for (i = 0; i < ctx->number_of_samples; i++) {
 uint16_t seed_shr7 = seed >> 7;
-*sample_buffer++ = ((int8_t)(seed >> 15)) << rh->noise_shift;
-*sample_buffer++ = ((int8_t) seed_shr7)   << rh->noise_shift;
+*sample_buffer++ = ((int8_t)(seed >> 15)) * (1 << rh->noise_shift);
+*sample_buffer++ = ((int8_t) seed_shr7)   * (1 << rh->noise_shift);
 
 seed = (seed << 16) ^ seed_shr7 ^ (seed_shr7 << 5);
 
@@ -2071,9 +2068,10 @@ static void set_best_codebook(MLPEncodeContext *ctx)
 best_codebook = *best_path++ - ZERO_PATH;
 cur_bo = >best_offset[index][channel][best_codebook];
 
-cp->huff_offset = cur_bo->offset;
-cp->huff_lsbs   = cur_bo->lsb_bits + dp->quant_step_size[channel];
-cp->codebook= best_codebook;
+cp->huff_offset  = cur_bo->offset;
+cp->sign_huff_offset = -(1 << 23);
+cp->huff_lsbs= cur_bo->lsb_bits + 
dp->quant_step_size[channel];
+cp->codebook = best_codebook;
 }
 }
 }
@@ -2275,7 +2273,7 @@ static int mlp_encode_frame(AVCodecContext *avctx, 
AVPacket *avpkt,
 if (restart_frame) {
 set_major_params(ctx);
 if (ctx->min_restart_interval != ctx->max_restart_interval)
-process_major_frame(ctx);
+process_major_frame(ctx);
 }
 
 if (ctx->min_restart_interval == ctx->max_restart_interval)
-- 
2.25.0

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

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

[FFmpeg-devel] [PATCH 2/5] mlpenc: fix huff offset calculation

2020-01-24 Thread Jai Luthra
huff offset wasn't always within the bounds before, which lead to
corrupt encoding that didn't always trigger lossless check failures

Signed-off-by: Jai Luthra 
---
 libavcodec/mlpenc.c | 6 +-
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/libavcodec/mlpenc.c b/libavcodec/mlpenc.c
index f4948451f1..1cee38c82f 100644
--- a/libavcodec/mlpenc.c
+++ b/libavcodec/mlpenc.c
@@ -1699,7 +1699,7 @@ static inline void codebook_bits(MLPEncodeContext *ctx,
 offset_min = FFMAX(min, HUFF_OFFSET_MIN);
 offset_max = FFMIN(max, HUFF_OFFSET_MAX);
 
-for (;;) {
+while (offset <= offset_max && offset >= offset_min) {
 BestOffset temp_bo;
 
 codebook_bits_offset(ctx, channel, codebook,
@@ -1718,12 +1718,8 @@ static inline void codebook_bits(MLPEncodeContext *ctx,
 
 if (direction) {
 offset = temp_bo.max + 1;
-if (offset > offset_max)
-break;
 } else {
 offset = temp_bo.min - 1;
-if (offset < offset_min)
-break;
 }
 }
 }
-- 
2.25.0

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

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

[FFmpeg-devel] [PATCH 0/5] mlpenc: fix lossless check failures for 16-bit encoding

2020-01-24 Thread Jai Luthra
This patchset fixes lossless check failures for 16-bit mlp/truehd encoding. 
Please check with more samples and let me know if you find any lossless 
failures.

Bug 6216 https://trac.ffmpeg.org/ticket/6216 still cannot be closed as last 
few frames aren't encoded, thus output is not bit-exact.
I will continue on the WIP patch Paul posted earlier and try to fix this.

32-bit encoding still has many lossless failures, so keeping it disabled for 
now. Will work on it later.

Jai Luthra (5):
  mlpenc: fix lossless check error in number_sbits
  mlpenc: fix huff offset calculation
  mlpenc: prevent negative lsb_bits lshift
  mlpenc: improve lpc filtering
  mlpenc: clean up

 libavcodec/mlpenc.c | 74 +
 1 file changed, 35 insertions(+), 39 deletions(-)

-- 
2.25.0

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

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

[FFmpeg-devel] [PATCH 4/5] mlpenc: improve lpc filtering

2020-01-24 Thread Jai Luthra
* fix a possible memory leak (apply_filter returned before freeing)
* use apply_filters in process_major_frame
* revert back to checking bounds with 24 bitdepth, as huff offset takes
care of it

Signed-off-by: Jai Luthra 
---
 libavcodec/mlpenc.c | 25 -
 1 file changed, 12 insertions(+), 13 deletions(-)

diff --git a/libavcodec/mlpenc.c b/libavcodec/mlpenc.c
index 41030f6f07..0e7a9b7640 100644
--- a/libavcodec/mlpenc.c
+++ b/libavcodec/mlpenc.c
@@ -1799,20 +1799,20 @@ static void determine_bits(MLPEncodeContext *ctx)
 
 /** Applies the filter to the current samples, and saves the residual back
  *  into the samples buffer. If the filter is too bad and overflows the
- *  maximum amount of bits allowed (16 or 24), the samples buffer is left as 
is and
+ *  maximum amount of bits allowed (24), the samples buffer is left as is and
  *  the function returns -1.
  */
 static int apply_filter(MLPEncodeContext *ctx, unsigned int channel)
 {
 FilterParams *fp[NUM_FILTERS] = { 
>cur_channel_params[channel].filter_params[FIR],
   
>cur_channel_params[channel].filter_params[IIR], };
-int32_t *filter_state_buffer[NUM_FILTERS];
+int32_t *filter_state_buffer[NUM_FILTERS] = { NULL };
 int32_t mask = 
MSB_MASK(ctx->cur_decoding_params->quant_step_size[channel]);
 int32_t *sample_buffer = ctx->sample_buffer + channel;
 unsigned int number_of_samples = ctx->number_of_samples;
 unsigned int filter_shift = fp[FIR]->shift;
 int filter;
-int i;
+int i, ret = 0;
 
 for (i = 0; i < NUM_FILTERS; i++) {
 unsigned int size = ctx->number_of_samples;
@@ -1835,7 +1835,7 @@ static int apply_filter(MLPEncodeContext *ctx, unsigned 
int channel)
 int32_t sample = *sample_buffer;
 unsigned int order;
 int64_t accum = 0;
-int32_t residual;
+int64_t residual;
 
 for (filter = 0; filter < NUM_FILTERS; filter++) {
 int32_t *fcoeff = ctx->cur_channel_params[channel].coeff[filter];
@@ -1847,11 +1847,13 @@ static int apply_filter(MLPEncodeContext *ctx, unsigned 
int channel)
 accum  >>= filter_shift;
 residual = sample - (accum & mask);
 
-if (residual < SAMPLE_MIN(ctx->wordlength) || residual > 
SAMPLE_MAX(ctx->wordlength))
-return -1;
+if (residual < SAMPLE_MIN(24) || residual > SAMPLE_MAX(24)) {
+ret = -1;
+goto free_and_return;
+}
 
 filter_state_buffer[FIR][i] = sample;
-filter_state_buffer[IIR][i] = residual;
+filter_state_buffer[IIR][i] = (int32_t) residual;
 
 sample_buffer += ctx->num_channels;
 }
@@ -1863,11 +1865,12 @@ static int apply_filter(MLPEncodeContext *ctx, unsigned 
int channel)
 sample_buffer += ctx->num_channels;
 }
 
+free_and_return:
 for (i = 0; i < NUM_FILTERS; i++) {
 av_freep(_state_buffer[i]);
 }
 
-return 0;
+return ret;
 }
 
 static void apply_filters(MLPEncodeContext *ctx)
@@ -2198,9 +2201,6 @@ static void process_major_frame(MLPEncodeContext *ctx)
 ctx->number_of_samples = ctx->major_frame_size;
 
 for (substr = 0; substr < ctx->num_substreams; substr++) {
-RestartHeader *rh = ctx->cur_restart_header;
-unsigned int channel;
-
 ctx->cur_restart_header = >restart_header[substr];
 
 ctx->cur_decoding_params = >major_decoding_params[1][substr];
@@ -2209,8 +2209,7 @@ static void process_major_frame(MLPEncodeContext *ctx)
 generate_2_noise_channels(ctx);
 rematrix_channels(ctx);
 
-for (channel = rh->min_channel; channel <= rh->max_channel; channel++)
-apply_filter(ctx, channel);
+apply_filters(ctx);
 }
 }
 
-- 
2.25.0

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

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

[FFmpeg-devel] [PATCH 3/5] mlpenc: prevent negative lsb_bits lshift

2020-01-24 Thread Jai Luthra
Fixes Coverity CID 1396239.

Signed-off-by: Jai Luthra 
---
 libavcodec/mlpenc.c | 11 +++
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/libavcodec/mlpenc.c b/libavcodec/mlpenc.c
index 1cee38c82f..41030f6f07 100644
--- a/libavcodec/mlpenc.c
+++ b/libavcodec/mlpenc.c
@@ -1,6 +1,7 @@
 /**
  * MLP encoder
  * Copyright (c) 2008 Ramiro Polla
+ * Copyright (c) 2016-2019 Jai Luthra
  *
  * This file is part of FFmpeg.
  *
@@ -1562,7 +1563,7 @@ static void no_codebook_bits_offset(MLPEncodeContext *ctx,
 BestOffset *bo)
 {
 DecodingParams *dp = ctx->cur_decoding_params;
-int32_t unsign;
+int32_t unsign = 0;
 int lsb_bits;
 
 min -= offset;
@@ -1572,7 +1573,8 @@ static void no_codebook_bits_offset(MLPEncodeContext *ctx,
 
 lsb_bits += !!lsb_bits;
 
-unsign = 1 << (lsb_bits - 1);
+if (lsb_bits > 0)
+unsign = 1 << (lsb_bits - 1);
 
 bo->offset   = offset;
 bo->lsb_bits = lsb_bits;
@@ -1591,7 +1593,7 @@ static void no_codebook_bits(MLPEncodeContext *ctx,
 {
 DecodingParams *dp = ctx->cur_decoding_params;
 int16_t offset;
-int32_t unsign;
+int32_t unsign = 0;
 uint32_t diff;
 int lsb_bits;
 
@@ -1607,7 +1609,8 @@ static void no_codebook_bits(MLPEncodeContext *ctx,
 
 lsb_bits = number_sbits(diff) - 1;
 
-unsign = 1 << (lsb_bits - 1);
+if (lsb_bits > 0)
+unsign = 1 << (lsb_bits - 1);
 
 /* If all samples are the same (lsb_bits == 0), offset must be
  * adjusted because of sign_shift. */
-- 
2.25.0

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

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

[FFmpeg-devel] [PATCH 1/5] mlpenc: fix lossless check error in number_sbits

2020-01-24 Thread Jai Luthra
we need two bits instead of one bit to represent -1 in bitstream

Signed-off-by: Jai Luthra 
---
 libavcodec/mlpenc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libavcodec/mlpenc.c b/libavcodec/mlpenc.c
index deb171645c..f4948451f1 100644
--- a/libavcodec/mlpenc.c
+++ b/libavcodec/mlpenc.c
@@ -466,7 +466,7 @@ static void default_decoding_params(MLPEncodeContext *ctx,
  */
 static int inline number_sbits(int number)
 {
-if (number < 0)
+if (number < -1)
 number++;
 
 return av_log2(FFABS(number)) + 1 + !!number;
-- 
2.25.0

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

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

[FFmpeg-devel] [PATCH 4/5 v2] mlpenc: improve lpc filtering

2019-07-09 Thread Jai Luthra
* fix a possible memory leak (apply_filter returned before freeing)
* use apply_filters in process_major_frame
* revert back to checking bounds with 24 bitdepth, as huff offset takes
care of it

Signed-off-by: Jai Luthra 
---

v2: remove unused variables in process_major_frame

---
 libavcodec/mlpenc.c | 23 +++
 1 file changed, 11 insertions(+), 12 deletions(-)

diff --git a/libavcodec/mlpenc.c b/libavcodec/mlpenc.c
index 41030f6f07..3c2a57d81a 100644
--- a/libavcodec/mlpenc.c
+++ b/libavcodec/mlpenc.c
@@ -1799,7 +1799,7 @@ static void determine_bits(MLPEncodeContext *ctx)
 
 /** Applies the filter to the current samples, and saves the residual back
  *  into the samples buffer. If the filter is too bad and overflows the
- *  maximum amount of bits allowed (16 or 24), the samples buffer is left as 
is and
+ *  maximum amount of bits allowed (24), the samples buffer is left as is and
  *  the function returns -1.
  */
 static int apply_filter(MLPEncodeContext *ctx, unsigned int channel)
@@ -1812,7 +1812,7 @@ static int apply_filter(MLPEncodeContext *ctx, unsigned 
int channel)
 unsigned int number_of_samples = ctx->number_of_samples;
 unsigned int filter_shift = fp[FIR]->shift;
 int filter;
-int i;
+int i, ret = 0;
 
 for (i = 0; i < NUM_FILTERS; i++) {
 unsigned int size = ctx->number_of_samples;
@@ -1835,7 +1835,7 @@ static int apply_filter(MLPEncodeContext *ctx, unsigned 
int channel)
 int32_t sample = *sample_buffer;
 unsigned int order;
 int64_t accum = 0;
-int32_t residual;
+int64_t residual;
 
 for (filter = 0; filter < NUM_FILTERS; filter++) {
 int32_t *fcoeff = ctx->cur_channel_params[channel].coeff[filter];
@@ -1847,11 +1847,13 @@ static int apply_filter(MLPEncodeContext *ctx, unsigned 
int channel)
 accum  >>= filter_shift;
 residual = sample - (accum & mask);
 
-if (residual < SAMPLE_MIN(ctx->wordlength) || residual > 
SAMPLE_MAX(ctx->wordlength))
-return -1;
+if (residual < SAMPLE_MIN(24) || residual > SAMPLE_MAX(24)) {
+ret = -1;
+goto free_and_return;
+}
 
 filter_state_buffer[FIR][i] = sample;
-filter_state_buffer[IIR][i] = residual;
+filter_state_buffer[IIR][i] = (int32_t) residual;
 
 sample_buffer += ctx->num_channels;
 }
@@ -1863,11 +1865,12 @@ static int apply_filter(MLPEncodeContext *ctx, unsigned 
int channel)
 sample_buffer += ctx->num_channels;
 }
 
+free_and_return:
 for (i = 0; i < NUM_FILTERS; i++) {
 av_freep(_state_buffer[i]);
 }
 
-return 0;
+return ret;
 }
 
 static void apply_filters(MLPEncodeContext *ctx)
@@ -2198,9 +2201,6 @@ static void process_major_frame(MLPEncodeContext *ctx)
 ctx->number_of_samples = ctx->major_frame_size;
 
 for (substr = 0; substr < ctx->num_substreams; substr++) {
-RestartHeader *rh = ctx->cur_restart_header;
-unsigned int channel;
-
 ctx->cur_restart_header = >restart_header[substr];
 
 ctx->cur_decoding_params = >major_decoding_params[1][substr];
@@ -2209,8 +2209,7 @@ static void process_major_frame(MLPEncodeContext *ctx)
 generate_2_noise_channels(ctx);
 rematrix_channels(ctx);
 
-for (channel = rh->min_channel; channel <= rh->max_channel; channel++)
-apply_filter(ctx, channel);
+apply_filters(ctx);
 }
 }
 
-- 
2.22.0

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

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

Re: [FFmpeg-devel] [PATCH 1/5] mlpenc: fix lossless check error in number_sbits

2019-07-09 Thread Jai Luthra

On Wed, Jul 10, 2019 at 12:14:56AM +0200, Lynne wrote:

Jul 9, 2019, 9:18 PM by m...@jailuthra.in:


we need two bits instead of one bit to represent -1 in bitstream

Signed-off-by: Jai Luthra 
---
 libavcodec/mlpenc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libavcodec/mlpenc.c b/libavcodec/mlpenc.c
index deb171645c..f4948451f1 100644
--- a/libavcodec/mlpenc.c
+++ b/libavcodec/mlpenc.c
@@ -466,7 +466,7 @@ static void default_decoding_params(MLPEncodeContext *ctx,
 */
 static int inline number_sbits(int number)
 {
-if (number < 0)
+if (number < -1)
 number++;



This is different from the first patch's version. Sure its correct now?


Yep. Previous patch produced valid bitstream too, but this provides better 
compression [1] by representing numbers of the form -2^x with one less bit for 
x >= 1.


This makes more sense, as we can represent -2 in two-bit twos-complement 
notation as `10` so output should be 2 bits (instead of 3 by previous patch). 
(similarly for -4, -8, -16, ...)


The lossless errors were being caused when a block of samples were all either 
-1 or 0. This function implied all samples could be represented as single bit 
each, but down the pipeline after huff vlc calculations, the encoder pushed 
 on the bitstream for all samples, which was always interpreted as 0 
by the decoder and never -1.


NB: One can argue -1 and 0 in fact can be represented in a single bit as two's 
complement, 0 being `0` and -1 being `1`. But imho, single bit two's 
complement is a weird boundary case, and not considering it solves the issue 
here. If someone has a better idea pls suggest.


[1]: tested using both patches on 
https://samples.ffmpeg.org/flac/When%20I%20Grow%20Up.flac. Previous patch 
compressed it to 28788216 byte MLP stream, this one compresses it to 28787834 
byte MLP stream. Both streams are valid and decode to lossless bit-exact 
output.


thx

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

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

Re: [FFmpeg-devel] [PATCH] mlpenc: fix lossless failures, add sanity checks

2019-07-09 Thread Jai Luthra

On Tue, Jul 09, 2019 at 08:26:19PM +0200, Carl Eugen Hoyos wrote:


Please split the patch into self-contained changes with appropriate commit 
messages.

Thank you, Carl Eugen


Cool, I've done more fixes will send a new patch set as a separate thread

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

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

[FFmpeg-devel] [PATCH 3/5] mlpenc: prevent negative lsb_bits lshift

2019-07-09 Thread Jai Luthra
Fixes Coverity CID 1396239.

Signed-off-by: Jai Luthra 
---
 libavcodec/mlpenc.c | 11 +++
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/libavcodec/mlpenc.c b/libavcodec/mlpenc.c
index 1cee38c82f..41030f6f07 100644
--- a/libavcodec/mlpenc.c
+++ b/libavcodec/mlpenc.c
@@ -1,6 +1,7 @@
 /**
  * MLP encoder
  * Copyright (c) 2008 Ramiro Polla
+ * Copyright (c) 2016-2019 Jai Luthra
  *
  * This file is part of FFmpeg.
  *
@@ -1562,7 +1563,7 @@ static void no_codebook_bits_offset(MLPEncodeContext *ctx,
 BestOffset *bo)
 {
 DecodingParams *dp = ctx->cur_decoding_params;
-int32_t unsign;
+int32_t unsign = 0;
 int lsb_bits;
 
 min -= offset;
@@ -1572,7 +1573,8 @@ static void no_codebook_bits_offset(MLPEncodeContext *ctx,
 
 lsb_bits += !!lsb_bits;
 
-unsign = 1 << (lsb_bits - 1);
+if (lsb_bits > 0)
+unsign = 1 << (lsb_bits - 1);
 
 bo->offset   = offset;
 bo->lsb_bits = lsb_bits;
@@ -1591,7 +1593,7 @@ static void no_codebook_bits(MLPEncodeContext *ctx,
 {
 DecodingParams *dp = ctx->cur_decoding_params;
 int16_t offset;
-int32_t unsign;
+int32_t unsign = 0;
 uint32_t diff;
 int lsb_bits;
 
@@ -1607,7 +1609,8 @@ static void no_codebook_bits(MLPEncodeContext *ctx,
 
 lsb_bits = number_sbits(diff) - 1;
 
-unsign = 1 << (lsb_bits - 1);
+if (lsb_bits > 0)
+unsign = 1 << (lsb_bits - 1);
 
 /* If all samples are the same (lsb_bits == 0), offset must be
  * adjusted because of sign_shift. */
-- 
2.22.0

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

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

[FFmpeg-devel] [PATCH 4/5] mlpenc: improve lpc filtering

2019-07-09 Thread Jai Luthra
* fix a possible memory leak (apply_filter returned before freeing)
* use apply_filters in process_major_frame
* revert back to checking bounds with 24 bitdepth, as huff offset takes
care of it

Signed-off-by: Jai Luthra 
---
 libavcodec/mlpenc.c | 20 +++-
 1 file changed, 11 insertions(+), 9 deletions(-)

diff --git a/libavcodec/mlpenc.c b/libavcodec/mlpenc.c
index 41030f6f07..9805e7ff23 100644
--- a/libavcodec/mlpenc.c
+++ b/libavcodec/mlpenc.c
@@ -1799,7 +1799,7 @@ static void determine_bits(MLPEncodeContext *ctx)
 
 /** Applies the filter to the current samples, and saves the residual back
  *  into the samples buffer. If the filter is too bad and overflows the
- *  maximum amount of bits allowed (16 or 24), the samples buffer is left as 
is and
+ *  maximum amount of bits allowed (24), the samples buffer is left as is and
  *  the function returns -1.
  */
 static int apply_filter(MLPEncodeContext *ctx, unsigned int channel)
@@ -1812,7 +1812,7 @@ static int apply_filter(MLPEncodeContext *ctx, unsigned 
int channel)
 unsigned int number_of_samples = ctx->number_of_samples;
 unsigned int filter_shift = fp[FIR]->shift;
 int filter;
-int i;
+int i, ret = 0;
 
 for (i = 0; i < NUM_FILTERS; i++) {
 unsigned int size = ctx->number_of_samples;
@@ -1835,7 +1835,7 @@ static int apply_filter(MLPEncodeContext *ctx, unsigned 
int channel)
 int32_t sample = *sample_buffer;
 unsigned int order;
 int64_t accum = 0;
-int32_t residual;
+int64_t residual;
 
 for (filter = 0; filter < NUM_FILTERS; filter++) {
 int32_t *fcoeff = ctx->cur_channel_params[channel].coeff[filter];
@@ -1847,11 +1847,13 @@ static int apply_filter(MLPEncodeContext *ctx, unsigned 
int channel)
 accum  >>= filter_shift;
 residual = sample - (accum & mask);
 
-if (residual < SAMPLE_MIN(ctx->wordlength) || residual > 
SAMPLE_MAX(ctx->wordlength))
-return -1;
+if (residual < SAMPLE_MIN(24) || residual > SAMPLE_MAX(24)) {
+ret = -1;
+goto free_and_return;
+}
 
 filter_state_buffer[FIR][i] = sample;
-filter_state_buffer[IIR][i] = residual;
+filter_state_buffer[IIR][i] = (int32_t) residual;
 
 sample_buffer += ctx->num_channels;
 }
@@ -1863,11 +1865,12 @@ static int apply_filter(MLPEncodeContext *ctx, unsigned 
int channel)
 sample_buffer += ctx->num_channels;
 }
 
+free_and_return:
 for (i = 0; i < NUM_FILTERS; i++) {
 av_freep(_state_buffer[i]);
 }
 
-return 0;
+return ret;
 }
 
 static void apply_filters(MLPEncodeContext *ctx)
@@ -2209,8 +2212,7 @@ static void process_major_frame(MLPEncodeContext *ctx)
 generate_2_noise_channels(ctx);
 rematrix_channels(ctx);
 
-for (channel = rh->min_channel; channel <= rh->max_channel; channel++)
-apply_filter(ctx, channel);
+apply_filters(ctx);
 }
 }
 
-- 
2.22.0

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

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

[FFmpeg-devel] [PATCH 5/5] mlpenc: clean up and enable 24-bit encoding

2019-07-09 Thread Jai Luthra
Signed-off-by: Jai Luthra 
---
 libavcodec/mlpenc.c | 34 --
 1 file changed, 16 insertions(+), 18 deletions(-)

diff --git a/libavcodec/mlpenc.c b/libavcodec/mlpenc.c
index 9805e7ff23..4124df6d8f 100644
--- a/libavcodec/mlpenc.c
+++ b/libavcodec/mlpenc.c
@@ -94,8 +94,8 @@ typedef struct BestOffset {
 int16_t max;
 } BestOffset;
 
-#define HUFF_OFFSET_MIN-16384
-#define HUFF_OFFSET_MAX 16383
+#define HUFF_OFFSET_MIN(-16384)
+#define HUFF_OFFSET_MAX( 16383)
 
 /** Number of possible codebooks (counting "no codebooks") */
 #define NUM_CODEBOOKS   4
@@ -808,7 +808,7 @@ static void write_major_sync(MLPEncodeContext *ctx, uint8_t 
*buf, int buf_size)
 static void write_restart_header(MLPEncodeContext *ctx, PutBitContext *pb)
 {
 RestartHeader *rh = ctx->cur_restart_header;
-int32_t lossless_check = xor_32_to_8(rh->lossless_check_data);
+uint8_t lossless_check = xor_32_to_8(rh->lossless_check_data);
 unsigned int start_count = put_bits_count(pb);
 PutBitContext tmpb;
 uint8_t checksum;
@@ -1017,12 +1017,10 @@ static void write_block_data(MLPEncodeContext *ctx, 
PutBitContext *pb)
 codebook_index  [ch] = cp->codebook  - 1;
 sign_huff_offset[ch] = cp->huff_offset;
 
-sign_shift = lsb_bits[ch] - 1;
+sign_shift = lsb_bits[ch] + (cp->codebook ? 2 - cp->codebook : -1);
 
-if (cp->codebook > 0) {
+if (cp->codebook > 0)
 sign_huff_offset[ch] -= 7 << lsb_bits[ch];
-sign_shift += 3 - cp->codebook;
-}
 
 /* Unsign if needed. */
 if (sign_shift >= 0)
@@ -1032,7 +1030,6 @@ static void write_block_data(MLPEncodeContext *ctx, 
PutBitContext *pb)
 for (i = 0; i < dp->blocksize; i++) {
 for (ch = rh->min_channel; ch <= rh->max_channel; ch++) {
 int32_t sample = *sample_buffer++ >> dp->quant_step_size[ch];
-
 sample -= sign_huff_offset[ch];
 
 if (codebook_index[ch] >= 0) {
@@ -1252,7 +1249,7 @@ static void input_data_internal(MLPEncodeContext *ctx, 
const uint8_t *samples,
 uint32_t abs_sample;
 int32_t sample;
 
-sample = is24 ? *samples_32++ >> 8 : *samples_16++ << 8;
+sample = is24 ? *samples_32++ >> 8 : *samples_16++ * 256U;
 
 /* TODO Find out if number_sbits can be used for negative 
values. */
 abs_sample = FFABS(sample);
@@ -1795,7 +1792,7 @@ static void determine_bits(MLPEncodeContext *ctx)
 #define SAMPLE_MAX(bitdepth) ((1 << (bitdepth - 1)) - 1)
 #define SAMPLE_MIN(bitdepth) (~SAMPLE_MAX(bitdepth))
 
-#define MSB_MASK(bits)  (-1u << bits)
+#define MSB_MASK(bits)  (-(1u << (bits)))
 
 /** Applies the filter to the current samples, and saves the residual back
  *  into the samples buffer. If the filter is too bad and overflows the
@@ -1899,8 +1896,8 @@ static void generate_2_noise_channels(MLPEncodeContext 
*ctx)
 
 for (i = 0; i < ctx->number_of_samples; i++) {
 uint16_t seed_shr7 = seed >> 7;
-*sample_buffer++ = ((int8_t)(seed >> 15)) << rh->noise_shift;
-*sample_buffer++ = ((int8_t) seed_shr7)   << rh->noise_shift;
+*sample_buffer++ = ((int8_t)(seed >> 15)) * (1 << rh->noise_shift);
+*sample_buffer++ = ((int8_t) seed_shr7)   * (1 << rh->noise_shift);
 
 seed = (seed << 16) ^ seed_shr7 ^ (seed_shr7 << 5);
 
@@ -2071,9 +2068,10 @@ static void set_best_codebook(MLPEncodeContext *ctx)
 best_codebook = *best_path++ - ZERO_PATH;
 cur_bo = >best_offset[index][channel][best_codebook];
 
-cp->huff_offset = cur_bo->offset;
-cp->huff_lsbs   = cur_bo->lsb_bits + dp->quant_step_size[channel];
-cp->codebook= best_codebook;
+cp->huff_offset  = cur_bo->offset;
+cp->sign_huff_offset = -(1 << 23);
+cp->huff_lsbs= cur_bo->lsb_bits + 
dp->quant_step_size[channel];
+cp->codebook = best_codebook;
 }
 }
 }
@@ -2278,7 +2276,7 @@ static int mlp_encode_frame(AVCodecContext *avctx, 
AVPacket *avpkt,
 if (restart_frame) {
 set_major_params(ctx);
 if (ctx->min_restart_interval != ctx->max_restart_interval)
-process_major_frame(ctx);
+process_major_frame(ctx);
 }
 
 if (ctx->min_restart_interval == ctx->max_restart_interval)
@@ -2392,7 +2390,7 @@ AVCodec ff_mlp_encoder = {
 .encode2= mlp_encode_frame,
 .close  = mlp_encode_close,
 .capabilities   = AV_CODEC_CAP_SMALL_LAST_FRAME | 
AV_CODEC_CAP_DELAY | AV_CODEC_CAP_EXPERIMENTAL,
-.sample_fmts= (const enum AVSampleFormat[]) 
{AV_S

[FFmpeg-devel] [PATCH 1/5] mlpenc: fix lossless check error in number_sbits

2019-07-09 Thread Jai Luthra
we need two bits instead of one bit to represent -1 in bitstream

Signed-off-by: Jai Luthra 
---
 libavcodec/mlpenc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libavcodec/mlpenc.c b/libavcodec/mlpenc.c
index deb171645c..f4948451f1 100644
--- a/libavcodec/mlpenc.c
+++ b/libavcodec/mlpenc.c
@@ -466,7 +466,7 @@ static void default_decoding_params(MLPEncodeContext *ctx,
  */
 static int inline number_sbits(int number)
 {
-if (number < 0)
+if (number < -1)
 number++;
 
 return av_log2(FFABS(number)) + 1 + !!number;
-- 
2.22.0

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

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

[FFmpeg-devel] [PATCH 2/5] mlpenc: fix huff offset calculation

2019-07-09 Thread Jai Luthra
huff offset wasn't always within the bounds before, which lead to
corrupt encoding that didn't always trigger lossless check failures

Signed-off-by: Jai Luthra 
---
 libavcodec/mlpenc.c | 6 +-
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/libavcodec/mlpenc.c b/libavcodec/mlpenc.c
index f4948451f1..1cee38c82f 100644
--- a/libavcodec/mlpenc.c
+++ b/libavcodec/mlpenc.c
@@ -1699,7 +1699,7 @@ static inline void codebook_bits(MLPEncodeContext *ctx,
 offset_min = FFMAX(min, HUFF_OFFSET_MIN);
 offset_max = FFMIN(max, HUFF_OFFSET_MAX);
 
-for (;;) {
+while (offset <= offset_max && offset >= offset_min) {
 BestOffset temp_bo;
 
 codebook_bits_offset(ctx, channel, codebook,
@@ -1718,12 +1718,8 @@ static inline void codebook_bits(MLPEncodeContext *ctx,
 
 if (direction) {
 offset = temp_bo.max + 1;
-if (offset > offset_max)
-break;
 } else {
 offset = temp_bo.min - 1;
-if (offset < offset_min)
-break;
 }
 }
 }
-- 
2.22.0

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

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

[FFmpeg-devel] [PATCH] mlpenc: fix lossless failures, add sanity checks

2019-07-09 Thread Jai Luthra
Signed-off-by: Jai Luthra 
---
 libavcodec/mlpenc.c | 72 +++--
 1 file changed, 37 insertions(+), 35 deletions(-)

diff --git a/libavcodec/mlpenc.c b/libavcodec/mlpenc.c
index deb171645c..09a8336b47 100644
--- a/libavcodec/mlpenc.c
+++ b/libavcodec/mlpenc.c
@@ -1,6 +1,7 @@
 /**
  * MLP encoder
  * Copyright (c) 2008 Ramiro Polla
+ * Copyright (c) 2016-2019 Jai Luthra
  *
  * This file is part of FFmpeg.
  *
@@ -26,6 +27,7 @@
 #include "libavutil/crc.h"
 #include "libavutil/avstring.h"
 #include "libavutil/samplefmt.h"
+#include "libavutil/avassert.h"
 #include "mlp.h"
 #include "lpc.h"
 
@@ -93,8 +95,8 @@ typedef struct BestOffset {
 int16_t max;
 } BestOffset;
 
-#define HUFF_OFFSET_MIN-16384
-#define HUFF_OFFSET_MAX 16383
+#define HUFF_OFFSET_MIN(-16384)
+#define HUFF_OFFSET_MAX( 16383)
 
 /** Number of possible codebooks (counting "no codebooks") */
 #define NUM_CODEBOOKS   4
@@ -466,9 +468,6 @@ static void default_decoding_params(MLPEncodeContext *ctx,
  */
 static int inline number_sbits(int number)
 {
-if (number < 0)
-number++;
-
 return av_log2(FFABS(number)) + 1 + !!number;
 }
 
@@ -807,7 +806,7 @@ static void write_major_sync(MLPEncodeContext *ctx, uint8_t 
*buf, int buf_size)
 static void write_restart_header(MLPEncodeContext *ctx, PutBitContext *pb)
 {
 RestartHeader *rh = ctx->cur_restart_header;
-int32_t lossless_check = xor_32_to_8(rh->lossless_check_data);
+uint8_t lossless_check = xor_32_to_8(rh->lossless_check_data);
 unsigned int start_count = put_bits_count(pb);
 PutBitContext tmpb;
 uint8_t checksum;
@@ -1016,12 +1015,10 @@ static void write_block_data(MLPEncodeContext *ctx, 
PutBitContext *pb)
 codebook_index  [ch] = cp->codebook  - 1;
 sign_huff_offset[ch] = cp->huff_offset;
 
-sign_shift = lsb_bits[ch] - 1;
+sign_shift = lsb_bits[ch] + (cp->codebook ? 2 - cp->codebook : -1);
 
-if (cp->codebook > 0) {
+if (cp->codebook > 0)
 sign_huff_offset[ch] -= 7 << lsb_bits[ch];
-sign_shift += 3 - cp->codebook;
-}
 
 /* Unsign if needed. */
 if (sign_shift >= 0)
@@ -1031,7 +1028,6 @@ static void write_block_data(MLPEncodeContext *ctx, 
PutBitContext *pb)
 for (i = 0; i < dp->blocksize; i++) {
 for (ch = rh->min_channel; ch <= rh->max_channel; ch++) {
 int32_t sample = *sample_buffer++ >> dp->quant_step_size[ch];
-
 sample -= sign_huff_offset[ch];
 
 if (codebook_index[ch] >= 0) {
@@ -1251,7 +1247,7 @@ static void input_data_internal(MLPEncodeContext *ctx, 
const uint8_t *samples,
 uint32_t abs_sample;
 int32_t sample;
 
-sample = is24 ? *samples_32++ >> 8 : *samples_16++ << 8;
+sample = is24 ? *samples_32++ >> 8 : *samples_16++ * 256U;
 
 /* TODO Find out if number_sbits can be used for negative 
values. */
 abs_sample = FFABS(sample);
@@ -1591,7 +1587,7 @@ static void no_codebook_bits(MLPEncodeContext *ctx,
 {
 DecodingParams *dp = ctx->cur_decoding_params;
 int16_t offset;
-int32_t unsign;
+int32_t unsign = 0;
 uint32_t diff;
 int lsb_bits;
 
@@ -1607,7 +1603,8 @@ static void no_codebook_bits(MLPEncodeContext *ctx,
 
 lsb_bits = number_sbits(diff) - 1;
 
-unsign = 1 << (lsb_bits - 1);
+if (lsb_bits > 0)
+unsign = 1 << (lsb_bits - 1);
 
 /* If all samples are the same (lsb_bits == 0), offset must be
  * adjusted because of sign_shift. */
@@ -1699,7 +1696,7 @@ static inline void codebook_bits(MLPEncodeContext *ctx,
 offset_min = FFMAX(min, HUFF_OFFSET_MIN);
 offset_max = FFMIN(max, HUFF_OFFSET_MAX);
 
-for (;;) {
+while (offset <= offset_max && offset >= offset_min) {
 BestOffset temp_bo;
 
 codebook_bits_offset(ctx, channel, codebook,
@@ -1709,6 +1706,7 @@ static inline void codebook_bits(MLPEncodeContext *ctx,
 if (temp_bo.bitcount < previous_count) {
 if (temp_bo.bitcount < bo->bitcount)
 *bo = temp_bo;
+av_assert0(bo->offset <= HUFF_OFFSET_MAX && bo->offset >= 
HUFF_OFFSET_MIN);
 
 is_greater = 0;
 } else if (++is_greater >= ctx->max_codebook_search)
@@ -1718,12 +1716,8 @@ static inline void codebook_bits(MLPEncodeContext *ctx,
 
 if (direction) {
 offset = temp_bo.max + 1;
-if (offset > offset_max)
-break;
 } else {
 offset = temp_bo.min - 1;
-if (offset < offset_min)
-break;
 }
 }
 }
@@ -1796,11 +1790,11 @@ static void determine_bits(MLPEncodeContext *ctx)

[FFmpeg-devel] [PATCH] MAINTAINERS: add myself for mlp/truehd

2016-09-17 Thread Jai Luthra
Signed-off-by: Jai Luthra <m...@jailuthra.in>
---
 MAINTAINERS | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index f7e8298..f1f991d 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -196,7 +196,7 @@ Codecs:
   mdec.cMichael Niedermayer
   mimic.c   Ramiro Polla
   mjpeg*.c  Michael Niedermayer
-  mlp*  Ramiro Polla
+  mlp*  Ramiro Polla, Jai Luthra
   mmvideo.c Peter Ross
   mpeg12.c, mpeg12data.hMichael Niedermayer
   mpegvideo.c, mpegvideo.h  Michael Niedermayer
-- 
2.7.4 (Apple Git-66)

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


Re: [FFmpeg-devel] [GSoC] [PATCH 2/2] mlpenc: Working MLP/TrueHD encoder

2016-09-17 Thread Jai Luthra
On Sat, Sep 17, 2016 at 05:07:28PM +0100, Andy Furniss wrote:
> Nice work, this is just a sort of related question really from a user
> who hasn't taken any notice of TrueHD for a few years.
>
> Last I looked I couldn't find much in the way of specs for TrueHD and
> noticed that the Decoder didn't have anything related to dynamic range
> control.
>
> Is there more info about now?
>
> IIRC testing decoder - (depending on content) for downmix or 2 channel
> sub stream the absence of DRC was a bit of a show stopper in that full
> range can be way too much. The AC3 version of course did have DRC meta
> and ffmpeg would correctly fully apply it for downmix, so for a stereo
> listener like me AC3 = good, TrueHD (or DTS) = bad.

The proprietary suite for TrueHD does support dynamic range compression, but I'm
unsure if (and where) the metadata for DRC is present in the bitstream.

The bitstream isn't fully reversed yet, just enough to get things working. I
think this is a very useful feature for downmixed substream to sound good, so
I'll try to figure it out in my spare time.

Cheers,

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


[FFmpeg-devel] [GSoC][PATCH v2 2/2] mlpenc: Working MLP/TrueHD encoder

2016-08-30 Thread Jai Luthra
* Multichannel support for TrueHD is experimental

There should be downmix substreams present for 2+ channel bitstreams,
but ffmpeg decoder doesn't need it. Will add support for this soon.

* There might be lossless check failures on LFE channels

* 32-bit sample support has been removed for now, will add it later

While testing, some samples gave lossless check failures when enforcing
s32. Probably this will also get solved with the LFE issues.

Signed-off-by: Jai Luthra <m...@jailuthra.in>
---

> a fate test could also be added

sure. i will add it in a separate patch later.

 libavcodec/Makefile|2 +
 libavcodec/allcodecs.c |4 +-
 libavcodec/mlp.c   |   21 +
 libavcodec/mlp.h   |   40 +
 libavcodec/mlpenc.c| 2416 
 5 files changed, 2481 insertions(+), 2 deletions(-)
 create mode 100644 libavcodec/mlpenc.c

diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index 7396468..b8d2a4c 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -382,6 +382,7 @@ OBJS-$(CONFIG_MJPEG_ENCODER)   += mjpegenc.o 
mjpegenc_common.o
 OBJS-$(CONFIG_MJPEGB_DECODER)  += mjpegbdec.o
 OBJS-$(CONFIG_MJPEG_VAAPI_ENCODER) += vaapi_encode_mjpeg.o
 OBJS-$(CONFIG_MLP_DECODER) += mlpdec.o mlpdsp.o
+OBJS-$(CONFIG_MLP_ENCODER) += mlpenc.o
 OBJS-$(CONFIG_MMVIDEO_DECODER) += mmvideo.o
 OBJS-$(CONFIG_MOTIONPIXELS_DECODER)+= motionpixels.o
 OBJS-$(CONFIG_MOVTEXT_DECODER) += movtextdec.o ass.o
@@ -545,6 +546,7 @@ OBJS-$(CONFIG_TIFF_DECODER)+= tiff.o lzw.o 
faxcompr.o tiff_data.o ti
 OBJS-$(CONFIG_TIFF_ENCODER)+= tiffenc.o rle.o lzwenc.o tiff_data.o
 OBJS-$(CONFIG_TMV_DECODER) += tmv.o cga_data.o
 OBJS-$(CONFIG_TRUEHD_DECODER)  += mlpdec.o mlpdsp.o
+OBJS-$(CONFIG_TRUEHD_ENCODER)  += mlpenc.o
 OBJS-$(CONFIG_TRUEMOTION1_DECODER) += truemotion1.o
 OBJS-$(CONFIG_TRUEMOTION2_DECODER) += truemotion2.o
 OBJS-$(CONFIG_TRUEMOTION2RT_DECODER)   += truemotion2rt.o
diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c
index 4c6b94e..64e0514 100644
--- a/libavcodec/allcodecs.c
+++ b/libavcodec/allcodecs.c
@@ -419,7 +419,7 @@ void avcodec_register_all(void)
 REGISTER_DECODER(MACE3, mace3);
 REGISTER_DECODER(MACE6, mace6);
 REGISTER_DECODER(METASOUND, metasound);
-REGISTER_DECODER(MLP,   mlp);
+REGISTER_ENCDEC (MLP,   mlp);
 REGISTER_DECODER(MP1,   mp1);
 REGISTER_DECODER(MP1FLOAT,  mp1float);
 REGISTER_ENCDEC (MP2,   mp2);
@@ -448,7 +448,7 @@ void avcodec_register_all(void)
 REGISTER_ENCDEC (SONIC, sonic);
 REGISTER_ENCODER(SONIC_LS,  sonic_ls);
 REGISTER_DECODER(TAK,   tak);
-REGISTER_DECODER(TRUEHD,truehd);
+REGISTER_ENCDEC (TRUEHD,truehd);
 REGISTER_DECODER(TRUESPEECH,truespeech);
 REGISTER_ENCDEC (TTA,   tta);
 REGISTER_DECODER(TWINVQ,twinvq);
diff --git a/libavcodec/mlp.c b/libavcodec/mlp.c
index 87f7c77..ddbab60 100644
--- a/libavcodec/mlp.c
+++ b/libavcodec/mlp.c
@@ -41,6 +41,27 @@ const uint8_t ff_mlp_huffman_tables[3][18][2] = {
 }
 };
 
+const ChannelInformation ff_mlp_ch_info[21] = {
+{ 0x01, 0x01, 0x00, 0x1f }, { 0x03, 0x02, 0x00, 0x1b },
+{ 0x07, 0x02, 0x01, 0x1f }, { 0x0F, 0x02, 0x02, 0x19 },
+{ 0x07, 0x02, 0x01, 0x03 }, { 0x0F, 0x02, 0x02, 0x1f },
+{ 0x1F, 0x02, 0x03, 0x01 }, { 0x07, 0x02, 0x01, 0x1a },
+{ 0x0F, 0x02, 0x02, 0x1f }, { 0x1F, 0x02, 0x03, 0x18 },
+{ 0x0F, 0x02, 0x02, 0x02 }, { 0x1F, 0x02, 0x03, 0x1f },
+{ 0x3F, 0x02, 0x04, 0x00 }, { 0x0F, 0x03, 0x01, 0x1f },
+{ 0x1F, 0x03, 0x02, 0x18 }, { 0x0F, 0x03, 0x01, 0x02 },
+{ 0x1F, 0x03, 0x02, 0x1f }, { 0x3F, 0x03, 0x03, 0x00 },
+{ 0x1F, 0x04, 0x01, 0x01 }, { 0x1F, 0x04, 0x01, 0x18 },
+{ 0x3F, 0x04, 0x02, 0x00 },
+};
+
+const uint64_t ff_mlp_channel_layouts[12] = {
+AV_CH_LAYOUT_MONO, AV_CH_LAYOUT_STEREO, AV_CH_LAYOUT_2_1,
+AV_CH_LAYOUT_QUAD, AV_CH_LAYOUT_2POINT1, AV_CH_LAYOUT_SURROUND,
+AV_CH_LAYOUT_4POINT0, AV_CH_LAYOUT_5POINT0_BACK, AV_CH_LAYOUT_3POINT1,
+AV_CH_LAYOUT_4POINT1, AV_CH_LAYOUT_5POINT1_BACK, 0,
+};
+
 static int crc_init = 0;
 #if CONFIG_SMALL
 #define CRC_TABLE_SIZE 257
diff --git a/libavcodec/mlp.h b/libavcodec/mlp.h
index 05d8dba..41a45a3 100644
--- a/libavcodec/mlp.h
+++ b/libavcodec/mlp.h
@@ -76,6 +76,9 @@ typedef struct FilterParams {
 uint8_t shift; ///< Right shift to apply to output of filter.
 
 int32_t state[MAX_FIR_ORDER];
+
+int coeff_bits;
+int coeff_shift;
 } FilterParams;
 
 /** sample data coding information */
@@ -96,6 +99,43 @@ typedef struct ChannelParams {
  */
 extern const uint8_t ff_mlp_huffman_tables[3][18][2];
 
+typedef struct {
+uint8_t channel_occupancy;
+uint8_t gro

[FFmpeg-devel] [GSoC] [PATCH 2/2] mlpenc: Working MLP/TrueHD encoder

2016-08-22 Thread Jai Luthra
* Multichannel support for TrueHD is experimental

There should be downmix substreams present for 2+ channel bitstreams,
but ffmpeg decoder doesn't need it. Will add support for this soon.

* There might be lossless check failures on LFE channels

* 32-bit sample support has been removed for now, will add it later

While testing, some samples gave lossless check failures when enforcing
s32. Probably this will also get solved with other lossless issues.

Signed-off-by: Jai Luthra <m...@jailuthra.in>
---
 libavcodec/Makefile|2 +
 libavcodec/allcodecs.c |4 +-
 libavcodec/mlp.c   |   21 +
 libavcodec/mlp.h   |   40 +
 libavcodec/mlpenc.c| 2416 
 5 files changed, 2481 insertions(+), 2 deletions(-)
 create mode 100644 libavcodec/mlpenc.c

diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index abef19e..b5a10a0 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -382,6 +382,7 @@ OBJS-$(CONFIG_MJPEG_ENCODER)   += mjpegenc.o 
mjpegenc_common.o
 OBJS-$(CONFIG_MJPEGB_DECODER)  += mjpegbdec.o
 OBJS-$(CONFIG_MJPEG_VAAPI_ENCODER) += vaapi_encode_mjpeg.o
 OBJS-$(CONFIG_MLP_DECODER) += mlpdec.o mlpdsp.o
+OBJS-$(CONFIG_MLP_ENCODER) += mlpenc.o
 OBJS-$(CONFIG_MMVIDEO_DECODER) += mmvideo.o
 OBJS-$(CONFIG_MOTIONPIXELS_DECODER)+= motionpixels.o
 OBJS-$(CONFIG_MOVTEXT_DECODER) += movtextdec.o ass.o
@@ -544,6 +545,7 @@ OBJS-$(CONFIG_TIFF_DECODER)+= tiff.o lzw.o 
faxcompr.o tiff_data.o ti
 OBJS-$(CONFIG_TIFF_ENCODER)+= tiffenc.o rle.o lzwenc.o tiff_data.o
 OBJS-$(CONFIG_TMV_DECODER) += tmv.o cga_data.o
 OBJS-$(CONFIG_TRUEHD_DECODER)  += mlpdec.o mlpdsp.o
+OBJS-$(CONFIG_TRUEHD_ENCODER)  += mlpenc.o
 OBJS-$(CONFIG_TRUEMOTION1_DECODER) += truemotion1.o
 OBJS-$(CONFIG_TRUEMOTION2_DECODER) += truemotion2.o
 OBJS-$(CONFIG_TRUEMOTION2RT_DECODER)   += truemotion2rt.o
diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c
index 951e199..e4ab8b3 100644
--- a/libavcodec/allcodecs.c
+++ b/libavcodec/allcodecs.c
@@ -419,7 +419,7 @@ void avcodec_register_all(void)
 REGISTER_DECODER(MACE3, mace3);
 REGISTER_DECODER(MACE6, mace6);
 REGISTER_DECODER(METASOUND, metasound);
-REGISTER_DECODER(MLP,   mlp);
+REGISTER_ENCDEC (MLP,   mlp);
 REGISTER_DECODER(MP1,   mp1);
 REGISTER_DECODER(MP1FLOAT,  mp1float);
 REGISTER_ENCDEC (MP2,   mp2);
@@ -448,7 +448,7 @@ void avcodec_register_all(void)
 REGISTER_ENCDEC (SONIC, sonic);
 REGISTER_ENCODER(SONIC_LS,  sonic_ls);
 REGISTER_DECODER(TAK,   tak);
-REGISTER_DECODER(TRUEHD,truehd);
+REGISTER_ENCDEC (TRUEHD,truehd);
 REGISTER_DECODER(TRUESPEECH,truespeech);
 REGISTER_ENCDEC (TTA,   tta);
 REGISTER_DECODER(TWINVQ,twinvq);
diff --git a/libavcodec/mlp.c b/libavcodec/mlp.c
index 87f7c77..ddbab60 100644
--- a/libavcodec/mlp.c
+++ b/libavcodec/mlp.c
@@ -41,6 +41,27 @@ const uint8_t ff_mlp_huffman_tables[3][18][2] = {
 }
 };
 
+const ChannelInformation ff_mlp_ch_info[21] = {
+{ 0x01, 0x01, 0x00, 0x1f }, { 0x03, 0x02, 0x00, 0x1b },
+{ 0x07, 0x02, 0x01, 0x1f }, { 0x0F, 0x02, 0x02, 0x19 },
+{ 0x07, 0x02, 0x01, 0x03 }, { 0x0F, 0x02, 0x02, 0x1f },
+{ 0x1F, 0x02, 0x03, 0x01 }, { 0x07, 0x02, 0x01, 0x1a },
+{ 0x0F, 0x02, 0x02, 0x1f }, { 0x1F, 0x02, 0x03, 0x18 },
+{ 0x0F, 0x02, 0x02, 0x02 }, { 0x1F, 0x02, 0x03, 0x1f },
+{ 0x3F, 0x02, 0x04, 0x00 }, { 0x0F, 0x03, 0x01, 0x1f },
+{ 0x1F, 0x03, 0x02, 0x18 }, { 0x0F, 0x03, 0x01, 0x02 },
+{ 0x1F, 0x03, 0x02, 0x1f }, { 0x3F, 0x03, 0x03, 0x00 },
+{ 0x1F, 0x04, 0x01, 0x01 }, { 0x1F, 0x04, 0x01, 0x18 },
+{ 0x3F, 0x04, 0x02, 0x00 },
+};
+
+const uint64_t ff_mlp_channel_layouts[12] = {
+AV_CH_LAYOUT_MONO, AV_CH_LAYOUT_STEREO, AV_CH_LAYOUT_2_1,
+AV_CH_LAYOUT_QUAD, AV_CH_LAYOUT_2POINT1, AV_CH_LAYOUT_SURROUND,
+AV_CH_LAYOUT_4POINT0, AV_CH_LAYOUT_5POINT0_BACK, AV_CH_LAYOUT_3POINT1,
+AV_CH_LAYOUT_4POINT1, AV_CH_LAYOUT_5POINT1_BACK, 0,
+};
+
 static int crc_init = 0;
 #if CONFIG_SMALL
 #define CRC_TABLE_SIZE 257
diff --git a/libavcodec/mlp.h b/libavcodec/mlp.h
index 05d8dba..41a45a3 100644
--- a/libavcodec/mlp.h
+++ b/libavcodec/mlp.h
@@ -76,6 +76,9 @@ typedef struct FilterParams {
 uint8_t shift; ///< Right shift to apply to output of filter.
 
 int32_t state[MAX_FIR_ORDER];
+
+int coeff_bits;
+int coeff_shift;
 } FilterParams;
 
 /** sample data coding information */
@@ -96,6 +99,43 @@ typedef struct ChannelParams {
  */
 extern const uint8_t ff_mlp_huffman_tables[3][18][2];
 
+typedef struct {
+uint8_t channel_occupancy;
+uint8_t group1_channels;
+uint8_t group2_channels;
+uint8_t summary_info;
+} ChannelIn

[FFmpeg-devel] [GSoC] [PATCH 1/2] lavc/lpc: Add min_shift parameter in LPC

2016-08-22 Thread Jai Luthra
The min_shift parameter is needed by the MLP encoder

Signed-off-by: Jai Luthra <m...@jailuthra.in>
---
 libavcodec/alacenc.c  |  4 +++-
 libavcodec/flacenc.c  |  3 ++-
 libavcodec/lpc.c  | 13 -
 libavcodec/lpc.h  |  2 +-
 libavcodec/ra144enc.c |  2 +-
 5 files changed, 15 insertions(+), 9 deletions(-)

diff --git a/libavcodec/alacenc.c b/libavcodec/alacenc.c
index 9ac35f1..6a887ff 100644
--- a/libavcodec/alacenc.c
+++ b/libavcodec/alacenc.c
@@ -38,6 +38,7 @@
 #define DEFAULT_MAX_PRED_ORDER6
 #define DEFAULT_MIN_PRED_ORDER4
 #define ALAC_MAX_LPC_PRECISION9
+#define ALAC_MIN_LPC_SHIFT0
 #define ALAC_MAX_LPC_SHIFT9
 
 #define ALAC_CHMODE_LEFT_RIGHT0
@@ -171,7 +172,8 @@ static void calc_predictor_params(AlacEncodeContext *s, int 
ch)
   s->max_prediction_order,
   ALAC_MAX_LPC_PRECISION, coefs, shift,
   FF_LPC_TYPE_LEVINSON, 0,
-  ORDER_METHOD_EST, ALAC_MAX_LPC_SHIFT, 1);
+  ORDER_METHOD_EST, ALAC_MIN_LPC_SHIFT,
+  ALAC_MAX_LPC_SHIFT, 1);
 
 s->lpc[ch].lpc_order = opt_order;
 s->lpc[ch].lpc_quant = shift[opt_order-1];
diff --git a/libavcodec/flacenc.c b/libavcodec/flacenc.c
index 9d6a742..3575f53 100644
--- a/libavcodec/flacenc.c
+++ b/libavcodec/flacenc.c
@@ -44,6 +44,7 @@
 #define MAX_PARTITION_ORDER 8
 #define MAX_PARTITIONS (1 << MAX_PARTITION_ORDER)
 #define MAX_LPC_PRECISION  15
+#define MIN_LPC_SHIFT   0
 #define MAX_LPC_SHIFT  15
 
 enum CodingMode {
@@ -884,7 +885,7 @@ static int encode_residual_ch(FlacEncodeContext *s, int ch)
 opt_order = ff_lpc_calc_coefs(>lpc_ctx, smp, n, min_order, max_order,
   s->options.lpc_coeff_precision, coefs, 
shift, s->options.lpc_type,
   s->options.lpc_passes, omethod,
-  MAX_LPC_SHIFT, 0);
+  MIN_LPC_SHIFT, MAX_LPC_SHIFT, 0);
 
 if (omethod == ORDER_METHOD_2LEVEL ||
 omethod == ORDER_METHOD_4LEVEL ||
diff --git a/libavcodec/lpc.c b/libavcodec/lpc.c
index 052aeaa..f8da1e1 100644
--- a/libavcodec/lpc.c
+++ b/libavcodec/lpc.c
@@ -93,7 +93,8 @@ static void lpc_compute_autocorr_c(const double *data, int 
len, int lag,
  * Quantize LPC coefficients
  */
 static void quantize_lpc_coefs(double *lpc_in, int order, int precision,
-   int32_t *lpc_out, int *shift, int max_shift, 
int zero_shift)
+   int32_t *lpc_out, int *shift, int min_shift,
+   int max_shift, int zero_shift)
 {
 int i;
 double cmax, error;
@@ -118,7 +119,7 @@ static void quantize_lpc_coefs(double *lpc_in, int order, 
int precision,
 
 /* calculate level shift which scales max coeff to available bits */
 sh = max_shift;
-while((cmax * (1 << sh) > qmax) && (sh > 0)) {
+while((cmax * (1 << sh) > qmax) && (sh > min_shift)) {
 sh--;
 }
 
@@ -201,7 +202,7 @@ int ff_lpc_calc_coefs(LPCContext *s,
   int max_order, int precision,
   int32_t coefs[][MAX_LPC_ORDER], int *shift,
   enum FFLPCType lpc_type, int lpc_passes,
-  int omethod, int max_shift, int zero_shift)
+  int omethod, int min_shift, int max_shift, int 
zero_shift)
 {
 double autoc[MAX_LPC_ORDER+1];
 double ref[MAX_LPC_ORDER] = { 0 };
@@ -284,10 +285,12 @@ int ff_lpc_calc_coefs(LPCContext *s,
 if(omethod == ORDER_METHOD_EST) {
 opt_order = estimate_best_order(ref, min_order, max_order);
 i = opt_order-1;
-quantize_lpc_coefs(lpc[i], i+1, precision, coefs[i], [i], 
max_shift, zero_shift);
+quantize_lpc_coefs(lpc[i], i+1, precision, coefs[i], [i],
+   min_shift, max_shift, zero_shift);
 } else {
 for(i=min_order-1; i<max_order; i++) {
-quantize_lpc_coefs(lpc[i], i+1, precision, coefs[i], [i], 
max_shift, zero_shift);
+quantize_lpc_coefs(lpc[i], i+1, precision, coefs[i], [i],
+   min_shift, max_shift, zero_shift);
 }
 }
 
diff --git a/libavcodec/lpc.h b/libavcodec/lpc.h
index edb1a6b..182adfa 100644
--- a/libavcodec/lpc.h
+++ b/libavcodec/lpc.h
@@ -95,7 +95,7 @@ int ff_lpc_calc_coefs(LPCContext *s,
   int max_order, int precision,
   int32_t coefs[][MAX_LPC_ORDER], int *shift,
   enum FFLPCType lpc_type, int lpc_passes,
-  int omethod, int max_shift, int zero_shift);
+  int omethod, int min_shift, int max_shift, int 
zero_shift);
 
 int ff_lpc_calc_ref_coefs(LPCContext *s,
   

Re: [FFmpeg-devel] [GSoC] MLP/TrueHD encoder

2016-07-28 Thread Jai Luthra
Hi,

Sorry for the late reply. I'll fix these issues tonight.

> more generally, is everything going acording to plan ?
> anything that you need help with ?

For now everything is going good. I ping atomnuker for updates or
whenever I'm stuck.

I've managed to encode 2-channel audio to a valid TrueHD bitstream
(decodes via ffmpeg).
I'm working on support for multiple channels for both MLP and TrueHD.
It is trivial for MLP, but doesn't look so for TrueHD; but I can
figure it out by comparing with the decoder.

I'll also need to test if the bitstream decodes on hardware and the
proprietary suite.

Cheers,
Jai Luthra
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


Re: [FFmpeg-devel] [GSoC] MLP/TrueHD encoder

2016-07-07 Thread Jai Luthra
On Thu, Jul 7, 2016 at 3:19 PM, Carl Eugen Hoyos wrote:
>
> Not necessarily related: Do you have an idea about how
> to fix ticket #5039?
> https://trac.ffmpeg.org/ticket/5039

Hi,

Looks like either ffmpeg's decoder is messing up when all samples in a
packet are same (likely; this might also explain similar errors in LFE
channel with MLP), or that the dolby encoder didn't do lossless
encoding (unlikely, but still a possibility).

I'll look into it for sure.

Cheers,
Jai Luthra (darkapex)
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


[FFmpeg-devel] [GSoC] MLP/TrueHD encoder

2016-07-06 Thread Jai Luthra
Hi,

This is an update for the TrueHD encoder gsoc project. Any input from the 
community about work done till now, or for plans ahead, is most welcome :)

The MLP encoder (patch attached) works without any lossless check errors now on 
most samples I've tested on, both for mono and stereo.

Here's the changelog from ramiro's original version of the encoder: 
https://github.com/jailuthra/FFmpeg/compare/33c37b86...b4eb87c

The current plan is:
* Support encoding TrueHD bitstreams through mlpenc.c, just like it's done 
in mlpdec.c
* Add multi-channel support
* Add FATE tests?
* Send the patch for review and merge

Also while testing how to implement multi-channel support, I noticed that the 
LFE channel encoding was not lossless for most samples. Any suggestions on how 
to fix this would be helpful.

Cheers,
Jai Luthra (darkapex)
From c73ea99b3cc1759f586eb9d19a4b8b46340e8823 Mon Sep 17 00:00:00 2001
From: Jai Luthra <m...@jailuthra.in>
Date: Wed, 2 Mar 2016 23:08:41 +0530
Subject: [PATCH] mlpenc: Add working encoder

Changes from ramiro's original work:
* Fixing lossless check failures
* Adding support for mono (support for more channels will come soon)
* Removed unused bitcount functions
* Fixing variable length array usages
* Minor updates to use new api

Signed-off-by: Jai Luthra <m...@jailuthra.in>
---
 libavcodec/Makefile|1 +
 libavcodec/alacenc.c   |4 +-
 libavcodec/allcodecs.c |2 +-
 libavcodec/flacenc.c   |3 +-
 libavcodec/lpc.c   |   13 +-
 libavcodec/lpc.h   |2 +-
 libavcodec/mlp.c   |   14 +
 libavcodec/mlp.h   |   38 +
 libavcodec/mlpenc.c| 2470 
 libavcodec/ra144enc.c  |2 +-
 10 files changed, 2539 insertions(+), 10 deletions(-)
 create mode 100644 libavcodec/mlpenc.c

diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index 46dd9e1..d72a48e 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -358,6 +358,7 @@ OBJS-$(CONFIG_MJPEG_ENCODER)   += mjpegenc.o mjpegenc_common.o
 OBJS-$(CONFIG_MJPEGB_DECODER)  += mjpegbdec.o
 OBJS-$(CONFIG_MJPEG_VAAPI_ENCODER) += vaapi_encode_mjpeg.o
 OBJS-$(CONFIG_MLP_DECODER) += mlpdec.o mlpdsp.o
+OBJS-$(CONFIG_MLP_ENCODER) += mlpenc.o
 OBJS-$(CONFIG_MMVIDEO_DECODER) += mmvideo.o
 OBJS-$(CONFIG_MOTIONPIXELS_DECODER)+= motionpixels.o
 OBJS-$(CONFIG_MOVTEXT_DECODER) += movtextdec.o ass.o
diff --git a/libavcodec/alacenc.c b/libavcodec/alacenc.c
index 9ac35f1..6a887ff 100644
--- a/libavcodec/alacenc.c
+++ b/libavcodec/alacenc.c
@@ -38,6 +38,7 @@
 #define DEFAULT_MAX_PRED_ORDER6
 #define DEFAULT_MIN_PRED_ORDER4
 #define ALAC_MAX_LPC_PRECISION9
+#define ALAC_MIN_LPC_SHIFT0
 #define ALAC_MAX_LPC_SHIFT9
 
 #define ALAC_CHMODE_LEFT_RIGHT0
@@ -171,7 +172,8 @@ static void calc_predictor_params(AlacEncodeContext *s, int ch)
   s->max_prediction_order,
   ALAC_MAX_LPC_PRECISION, coefs, shift,
   FF_LPC_TYPE_LEVINSON, 0,
-  ORDER_METHOD_EST, ALAC_MAX_LPC_SHIFT, 1);
+  ORDER_METHOD_EST, ALAC_MIN_LPC_SHIFT,
+  ALAC_MAX_LPC_SHIFT, 1);
 
 s->lpc[ch].lpc_order = opt_order;
 s->lpc[ch].lpc_quant = shift[opt_order-1];
diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c
index 6d0a7e7..f6a99e9 100644
--- a/libavcodec/allcodecs.c
+++ b/libavcodec/allcodecs.c
@@ -410,7 +410,7 @@ void avcodec_register_all(void)
 REGISTER_DECODER(MACE3, mace3);
 REGISTER_DECODER(MACE6, mace6);
 REGISTER_DECODER(METASOUND, metasound);
-REGISTER_DECODER(MLP,   mlp);
+REGISTER_ENCDEC (MLP,   mlp);
 REGISTER_DECODER(MP1,   mp1);
 REGISTER_DECODER(MP1FLOAT,  mp1float);
 REGISTER_ENCDEC (MP2,   mp2);
diff --git a/libavcodec/flacenc.c b/libavcodec/flacenc.c
index a91ed19..e0f0880 100644
--- a/libavcodec/flacenc.c
+++ b/libavcodec/flacenc.c
@@ -43,6 +43,7 @@
 #define MAX_PARTITION_ORDER 8
 #define MAX_PARTITIONS (1 << MAX_PARTITION_ORDER)
 #define MAX_LPC_PRECISION  15
+#define MIN_LPC_SHIFT   0
 #define MAX_LPC_SHIFT  15
 
 enum CodingMode {
@@ -883,7 +884,7 @@ static int encode_residual_ch(FlacEncodeContext *s, int ch)
 opt_order = ff_lpc_calc_coefs(>lpc_ctx, smp, n, min_order, max_order,
   s->options.lpc_coeff_precision, coefs, shift, s->options.lpc_type,
   s->options.lpc_passes, omethod,
-  MAX_LPC_SHIFT, 0);
+  MIN_LPC_SHIFT, MAX_LPC_SHIFT, 0);
 
 if (omethod == ORDER_METHOD_2LEVEL ||
 omethod == ORDER_METHOD_4LEVEL ||
diff --git a/libavcodec

Re: [FFmpeg-devel] [PATCH] [WIP] Updated MLP encoder - Qualification Task (TrueHD)

2016-04-09 Thread Jai Luthra
Hi,

I've updated the patch (attached):
* Fixed the build warnings
* Applied atomnuker's changes to update the mlp_encode_frame function
* Added AudioFrameQueue as suggested by atomnuker

The encoder now works without any errors to silence and can encode
stereo files with a valid bitstream.

I guess the qualification task is now complete (except validating
bitstream without using ffmpeg)

I've noticed that it doesn't generate valid bitstream for mono files.
ffplay's output is full of:
[mlp @ 0x7fd2b4001980] No restart header present in substream 0.
[mlp @ 0x7fd2b4001980] No samples to output.
[mlp @ 0x7fd2b4001980] Max channel must be equal max matrix channel.

I'll find a fix for this asap, and might need some help from the mentor if I
get stuck.

Cheers,
Jai Luthra
From e2748f6a65ffedf7b79a76c20bbbf17665f66ae2 Mon Sep 17 00:00:00 2001
From: Jai Luthra <m...@jailuthra.in>
Date: Wed, 2 Mar 2016 23:08:41 +0530
Subject: [PATCH] mlpenc: Add compilable mlp encoder

Signed-off-by: Jai Luthra <m...@jailuthra.in>
---
 libavcodec/Makefile|1 +
 libavcodec/alacenc.c   |4 +-
 libavcodec/allcodecs.c |2 +-
 libavcodec/flacenc.c   |3 +-
 libavcodec/lpc.c   |   13 +-
 libavcodec/lpc.h   |2 +-
 libavcodec/mlp.c   |   14 +
 libavcodec/mlp.h   |   38 +
 libavcodec/mlpenc.c| 2450 
 libavcodec/ra144enc.c  |2 +-
 10 files changed, 2519 insertions(+), 10 deletions(-)
 create mode 100644 libavcodec/mlpenc.c

diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index 8e6563c..e03514a 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -360,6 +360,7 @@ OBJS-$(CONFIG_MJPEG_DECODER)   += mjpegdec.o
 OBJS-$(CONFIG_MJPEG_ENCODER)   += mjpegenc.o mjpegenc_common.o
 OBJS-$(CONFIG_MJPEGB_DECODER)  += mjpegbdec.o
 OBJS-$(CONFIG_MLP_DECODER) += mlpdec.o mlpdsp.o
+OBJS-$(CONFIG_MLP_ENCODER) += mlpenc.o
 OBJS-$(CONFIG_MMVIDEO_DECODER) += mmvideo.o
 OBJS-$(CONFIG_MOTIONPIXELS_DECODER)+= motionpixels.o
 OBJS-$(CONFIG_MOVTEXT_DECODER) += movtextdec.o ass.o
diff --git a/libavcodec/alacenc.c b/libavcodec/alacenc.c
index c80c887..303fa26 100644
--- a/libavcodec/alacenc.c
+++ b/libavcodec/alacenc.c
@@ -38,6 +38,7 @@
 #define DEFAULT_MAX_PRED_ORDER6
 #define DEFAULT_MIN_PRED_ORDER4
 #define ALAC_MAX_LPC_PRECISION9
+#define ALAC_MIN_LPC_SHIFT0
 #define ALAC_MAX_LPC_SHIFT9
 
 #define ALAC_CHMODE_LEFT_RIGHT0
@@ -171,7 +172,8 @@ static void calc_predictor_params(AlacEncodeContext *s, int ch)
   s->max_prediction_order,
   ALAC_MAX_LPC_PRECISION, coefs, shift,
   FF_LPC_TYPE_LEVINSON, 0,
-  ORDER_METHOD_EST, ALAC_MAX_LPC_SHIFT, 1);
+  ORDER_METHOD_EST, ALAC_MIN_LPC_SHIFT,
+  ALAC_MAX_LPC_SHIFT, 1);
 
 s->lpc[ch].lpc_order = opt_order;
 s->lpc[ch].lpc_quant = shift[opt_order-1];
diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c
index 3214e35..352ffae 100644
--- a/libavcodec/allcodecs.c
+++ b/libavcodec/allcodecs.c
@@ -414,7 +414,7 @@ void avcodec_register_all(void)
 REGISTER_DECODER(MACE3, mace3);
 REGISTER_DECODER(MACE6, mace6);
 REGISTER_DECODER(METASOUND, metasound);
-REGISTER_DECODER(MLP,   mlp);
+REGISTER_ENCDEC (MLP,   mlp);
 REGISTER_DECODER(MP1,   mp1);
 REGISTER_DECODER(MP1FLOAT,  mp1float);
 REGISTER_ENCDEC (MP2,   mp2);
diff --git a/libavcodec/flacenc.c b/libavcodec/flacenc.c
index a91ed19..e0f0880 100644
--- a/libavcodec/flacenc.c
+++ b/libavcodec/flacenc.c
@@ -43,6 +43,7 @@
 #define MAX_PARTITION_ORDER 8
 #define MAX_PARTITIONS (1 << MAX_PARTITION_ORDER)
 #define MAX_LPC_PRECISION  15
+#define MIN_LPC_SHIFT   0
 #define MAX_LPC_SHIFT  15
 
 enum CodingMode {
@@ -883,7 +884,7 @@ static int encode_residual_ch(FlacEncodeContext *s, int ch)
 opt_order = ff_lpc_calc_coefs(>lpc_ctx, smp, n, min_order, max_order,
   s->options.lpc_coeff_precision, coefs, shift, s->options.lpc_type,
   s->options.lpc_passes, omethod,
-  MAX_LPC_SHIFT, 0);
+  MIN_LPC_SHIFT, MAX_LPC_SHIFT, 0);
 
 if (omethod == ORDER_METHOD_2LEVEL ||
 omethod == ORDER_METHOD_4LEVEL ||
diff --git a/libavcodec/lpc.c b/libavcodec/lpc.c
index 052aeaa..f8da1e1 100644
--- a/libavcodec/lpc.c
+++ b/libavcodec/lpc.c
@@ -93,7 +93,8 @@ static void lpc_compute_autocorr_c(const double *data, int len, int lag,
  * Quantize LPC coefficients
  */
 static void quantize_lpc_coefs(double *lpc_in, int order, int precision,
- 

Re: [FFmpeg-devel] [PATCH] [WIP] Updated MLP encoder - Qualification Task (TrueHD)

2016-04-05 Thread Jai Luthra
Hi,

On Tue, Apr 05, 2016 at 10:31:44PM +0200, Michael Niedermayer wrote:
> > Should I squash the commits and send a single patch instead?
> 
> a single patch makes more sense for reviewing
Cool. I've attached the squashed patch for review.

> > PS: I noticed Disha Singh is also working on this for outreachy. Is it
> > fine if two applicants work on the same project through different
> > programs over the summer?
> 
> It is possible AFAIK, but its unlikely we will accept 2 students doing
> exactly the same
> So far noone has passed the qualfication task for this project though
I'll complete it and submit for final evaluation within a week.
Sorry for being late, I was busy with college studies but I'll be completely
free during the coding period.

Cheers,
Jai Luthra
From 6190f169d87523af12c9a5187dc3a8019d066c3f Mon Sep 17 00:00:00 2001
From: Jai Luthra <m...@jailuthra.in>
Date: Wed, 2 Mar 2016 23:08:41 +0530
Subject: [PATCH] mlpenc: Add compilable mlp encoder

Signed-off-by: Jai Luthra <m...@jailuthra.in>
---
 libavcodec/Makefile|1 +
 libavcodec/alacenc.c   |4 +-
 libavcodec/allcodecs.c |2 +-
 libavcodec/flacenc.c   |3 +-
 libavcodec/lpc.c   |   13 +-
 libavcodec/lpc.h   |2 +-
 libavcodec/mlp.c   |   14 +
 libavcodec/mlp.h   |   38 +
 libavcodec/mlpenc.c| 2426 
 libavcodec/ra144enc.c  |2 +-
 10 files changed, 2495 insertions(+), 10 deletions(-)
 create mode 100644 libavcodec/mlpenc.c

diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index 8e6563c..e03514a 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -360,6 +360,7 @@ OBJS-$(CONFIG_MJPEG_DECODER)   += mjpegdec.o
 OBJS-$(CONFIG_MJPEG_ENCODER)   += mjpegenc.o mjpegenc_common.o
 OBJS-$(CONFIG_MJPEGB_DECODER)  += mjpegbdec.o
 OBJS-$(CONFIG_MLP_DECODER) += mlpdec.o mlpdsp.o
+OBJS-$(CONFIG_MLP_ENCODER) += mlpenc.o
 OBJS-$(CONFIG_MMVIDEO_DECODER) += mmvideo.o
 OBJS-$(CONFIG_MOTIONPIXELS_DECODER)+= motionpixels.o
 OBJS-$(CONFIG_MOVTEXT_DECODER) += movtextdec.o ass.o
diff --git a/libavcodec/alacenc.c b/libavcodec/alacenc.c
index c80c887..303fa26 100644
--- a/libavcodec/alacenc.c
+++ b/libavcodec/alacenc.c
@@ -38,6 +38,7 @@
 #define DEFAULT_MAX_PRED_ORDER6
 #define DEFAULT_MIN_PRED_ORDER4
 #define ALAC_MAX_LPC_PRECISION9
+#define ALAC_MIN_LPC_SHIFT0
 #define ALAC_MAX_LPC_SHIFT9
 
 #define ALAC_CHMODE_LEFT_RIGHT0
@@ -171,7 +172,8 @@ static void calc_predictor_params(AlacEncodeContext *s, int ch)
   s->max_prediction_order,
   ALAC_MAX_LPC_PRECISION, coefs, shift,
   FF_LPC_TYPE_LEVINSON, 0,
-  ORDER_METHOD_EST, ALAC_MAX_LPC_SHIFT, 1);
+  ORDER_METHOD_EST, ALAC_MIN_LPC_SHIFT,
+  ALAC_MAX_LPC_SHIFT, 1);
 
 s->lpc[ch].lpc_order = opt_order;
 s->lpc[ch].lpc_quant = shift[opt_order-1];
diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c
index 3214e35..352ffae 100644
--- a/libavcodec/allcodecs.c
+++ b/libavcodec/allcodecs.c
@@ -414,7 +414,7 @@ void avcodec_register_all(void)
 REGISTER_DECODER(MACE3, mace3);
 REGISTER_DECODER(MACE6, mace6);
 REGISTER_DECODER(METASOUND, metasound);
-REGISTER_DECODER(MLP,   mlp);
+REGISTER_ENCDEC (MLP,   mlp);
 REGISTER_DECODER(MP1,   mp1);
 REGISTER_DECODER(MP1FLOAT,  mp1float);
 REGISTER_ENCDEC (MP2,   mp2);
diff --git a/libavcodec/flacenc.c b/libavcodec/flacenc.c
index a91ed19..e0f0880 100644
--- a/libavcodec/flacenc.c
+++ b/libavcodec/flacenc.c
@@ -43,6 +43,7 @@
 #define MAX_PARTITION_ORDER 8
 #define MAX_PARTITIONS (1 << MAX_PARTITION_ORDER)
 #define MAX_LPC_PRECISION  15
+#define MIN_LPC_SHIFT   0
 #define MAX_LPC_SHIFT  15
 
 enum CodingMode {
@@ -883,7 +884,7 @@ static int encode_residual_ch(FlacEncodeContext *s, int ch)
 opt_order = ff_lpc_calc_coefs(>lpc_ctx, smp, n, min_order, max_order,
   s->options.lpc_coeff_precision, coefs, shift, s->options.lpc_type,
   s->options.lpc_passes, omethod,
-  MAX_LPC_SHIFT, 0);
+  MIN_LPC_SHIFT, MAX_LPC_SHIFT, 0);
 
 if (omethod == ORDER_METHOD_2LEVEL ||
 omethod == ORDER_METHOD_4LEVEL ||
diff --git a/libavcodec/lpc.c b/libavcodec/lpc.c
index 052aeaa..f8da1e1 100644
--- a/libavcodec/lpc.c
+++ b/libavcodec/lpc.c
@@ -93,7 +93,8 @@ static void lpc_compute_autocorr_c(const double *data, int len, int lag,
  * Quantize LPC coefficients
  */
 static void quantize_lpc_coefs(double *lpc_in, int order,

[FFmpeg-devel] [PATCH] [WIP] Updated MLP encoder - Qualification Task (TrueHD)

2016-04-05 Thread Jai Luthra
Hi,

I've almost finished my qualfication task for GSoC, and would love some
input on my work till now.

Currently, the mlp encoder compiles, but does not produce valid
bitstream (crashes). This is because AVCodec's encode2 function prototype has
changed, but the mlp_encode_frame assumes the old api.

I have to update it, any pointers for doing this? Should I just look at
other encoders and try to follow how they implement the encode_frame
function?

Also, I still have to make the changes in the mallocs suggested by my
mentor on IRC.
I'll send the updated patches within a week.

Should I squash the commits and send a single patch instead?

Cheers,
Jai Luthra

PS: I noticed Disha Singh is also working on this for outreachy. Is it
fine if two applicants work on the same project through different
programs over the summer?
From 4ed2b13f7b263aaca0aa0caea7153aa64785948a Mon Sep 17 00:00:00 2001
From: Jai Luthra <m...@jailuthra.in>
Date: Wed, 2 Mar 2016 23:08:41 +0530
Subject: [PATCH 1/9] mlpenc: Add ramiro's work

Add the mlp encoder written by Ramiro Polla
https://github.com/ramiropolla/soc/blob/master/mlp/mlpenc.c

Signed-off-by: Jai Luthra <m...@jailuthra.in>
---
 libavcodec/mlpenc.c | 2422 +++
 1 file changed, 2422 insertions(+)
 create mode 100644 libavcodec/mlpenc.c

diff --git a/libavcodec/mlpenc.c b/libavcodec/mlpenc.c
new file mode 100644
index 000..70cb7d8
--- /dev/null
+++ b/libavcodec/mlpenc.c
@@ -0,0 +1,2422 @@
+/**
+ * MLP encoder
+ * Copyright (c) 2008 Ramiro Polla <ram...@lisha.ufsc.br>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "avcodec.h"
+#include "put_bits.h"
+#include "libavutil/crc.h"
+#include "libavutil/avstring.h"
+#include "mlp.h"
+#include "dsputil.h"
+#include "lpc.h"
+
+#define MAJOR_HEADER_INTERVAL 16
+
+#define MLP_MIN_LPC_ORDER  1
+#define MLP_MAX_LPC_ORDER  8
+#define MLP_MIN_LPC_SHIFT  8
+#define MLP_MAX_LPC_SHIFT 15
+
+typedef struct {
+uint8_t min_channel; ///< The index of the first channel coded in this substream.
+uint8_t max_channel; ///< The index of the last channel coded in this substream.
+uint8_t max_matrix_channel;  ///< The number of channels input into the rematrix stage.
+
+uint8_t noise_shift; ///< The left shift applied to random noise in 0x31ea substreams.
+uint32_tnoisegen_seed;   ///< The current seed value for the pseudorandom noise generator(s).
+
+int data_check_present;  ///< Set if the substream contains extra info to check the size of VLC blocks.
+
+int32_t lossless_check_data; ///< XOR of all output samples
+
+uint8_t max_huff_lsbs;   ///< largest huff_lsbs
+uint8_t max_output_bits; ///< largest output bit-depth
+} RestartHeader;
+
+typedef struct {
+uint8_t count;  ///< number of matrices to apply
+
+uint8_t outch[MAX_MATRICES];///< output channel for each matrix
+int32_t forco[MAX_MATRICES][MAX_CHANNELS+2];///< forward coefficients
+int32_t coeff[MAX_MATRICES][MAX_CHANNELS+2];///< decoding coefficients
+uint8_t fbits[MAX_CHANNELS];///< fraction bits
+
+int8_t  shift[MAX_CHANNELS];///< Left shift to apply to decoded PCM values to get final 24-bit output.
+} MatrixParams;
+
+typedef struct {
+uint16_tblocksize;  ///< number of PCM samples in current audio block
+uint8_t quant_step_size[MAX_CHANNELS];  ///< left shift to apply to Huffman-decoded residuals
+
+MatrixParamsmatrix_params;
+
+uint8_t param_presence_flags;   ///< Bitmask of which parameter sets are conveyed in a decoding parameter block.
+#define PARAM_PRESENCE_FLAGS(1 << 8)
+
+#define PARAMS_DEFAULT  (0xFF)
+#define PARAM_BLOCKSIZE (1 << 7)
+#define PARAM_MATRIX(1 << 6)
+#define PARAM_OUTSHIFT  (1 << 5)
+#define PARAM_QUANTSTEP (1 << 4)
+#define PARAM_FIR