Re: [libav-devel] [PATCH] rtsp: add pkt_size option

2019-04-15 Thread Tristan Matthews
On Thu, Apr 11, 2019 at 1:41 AM Martin Storsjö  wrote:
>
> On Thu, 11 Apr 2019, Tristan Matthews wrote:
>
> > This allows users to specify an upper limit on the size of outgoing packets
> > when publishing via RTSP.
> >
> > ---
> > libavformat/rtsp.c | 5 -
> > libavformat/rtsp.h | 1 +
> > 2 files changed, 5 insertions(+), 1 deletion(-)
> >
> > diff --git a/libavformat/rtsp.c b/libavformat/rtsp.c
> > index 8bf9d9e3c..12c4998c6 100644
> > --- a/libavformat/rtsp.c
> > +++ b/libavformat/rtsp.c
> > @@ -74,7 +74,8 @@
> >
> > #define COMMON_OPTS() \
> > { "reorder_queue_size", "Number of packets to buffer for handling of 
> > reordered packets", OFFSET(reordering_queue_size), AV_OPT_TYPE_INT, { .i64 
> > = -1 }, -1, INT_MAX, DEC }, \
> > -{ "buffer_size","Underlying protocol send/receive buffer 
> > size",  OFFSET(buffer_size),   AV_OPT_TYPE_INT, { 
> > .i64 = -1 }, -1, INT_MAX, DEC|ENC } \
> > +{ "buffer_size","Underlying protocol send/receive buffer 
> > size",  OFFSET(buffer_size),   AV_OPT_TYPE_INT, { 
> > .i64 = -1 }, -1, INT_MAX, DEC|ENC }, \
> > +{ "pkt_size",   "Underlying protocol send packet size",
> >   OFFSET(pkt_size),  AV_OPT_TYPE_INT, { .i64 = 
> > -1 }, -1, INT_MAX, ENC } \
> >
> >
> > const AVOption ff_rtsp_options[] = {
> > @@ -118,6 +119,8 @@ static AVDictionary *map_to_opts(RTSPState *rt)
> >
> > snprintf(buf, sizeof(buf), "%d", rt->buffer_size);
> > av_dict_set(&opts, "buffer_size", buf, 0);
> > +snprintf(buf, sizeof(buf), "%d", rt->pkt_size);
> > +av_dict_set(&opts, "pkt_size", buf, 0);
> >
> > return opts;
> > }
> > diff --git a/libavformat/rtsp.h b/libavformat/rtsp.h
> > index 9dfbc5367..c38b90432 100644
> > --- a/libavformat/rtsp.h
> > +++ b/libavformat/rtsp.h
> > @@ -399,6 +399,7 @@ typedef struct RTSPState {
> >
> > char default_lang[4];
> > int buffer_size;
> > +int pkt_size;
> >
> > const URLProtocol **protocols;
> > } RTSPState;
> > --
> > 2.17.1
>
> LGTM
>
> // Martin

This OK to merge?
___
libav-devel mailing list
libav-devel@libav.org
https://lists.libav.org/mailman/listinfo/libav-devel

[libav-devel] [PATCH] rtsp: add pkt_size option

2019-04-10 Thread Tristan Matthews
This allows users to specify an upper limit on the size of outgoing packets
when publishing via RTSP.

---
 libavformat/rtsp.c | 5 -
 libavformat/rtsp.h | 1 +
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/libavformat/rtsp.c b/libavformat/rtsp.c
index 8bf9d9e3c..12c4998c6 100644
--- a/libavformat/rtsp.c
+++ b/libavformat/rtsp.c
@@ -74,7 +74,8 @@
 
 #define COMMON_OPTS() \
 { "reorder_queue_size", "Number of packets to buffer for handling of 
reordered packets", OFFSET(reordering_queue_size), AV_OPT_TYPE_INT, { .i64 = -1 
}, -1, INT_MAX, DEC }, \
-{ "buffer_size","Underlying protocol send/receive buffer size",
  OFFSET(buffer_size),   AV_OPT_TYPE_INT, { .i64 = -1 }, 
-1, INT_MAX, DEC|ENC } \
+{ "buffer_size","Underlying protocol send/receive buffer size",
  OFFSET(buffer_size),   AV_OPT_TYPE_INT, { .i64 = -1 }, 
-1, INT_MAX, DEC|ENC }, \
+{ "pkt_size",   "Underlying protocol send packet size",
  OFFSET(pkt_size),  AV_OPT_TYPE_INT, { .i64 = -1 }, 
-1, INT_MAX, ENC } \
 
 
 const AVOption ff_rtsp_options[] = {
@@ -118,6 +119,8 @@ static AVDictionary *map_to_opts(RTSPState *rt)
 
 snprintf(buf, sizeof(buf), "%d", rt->buffer_size);
 av_dict_set(&opts, "buffer_size", buf, 0);
+snprintf(buf, sizeof(buf), "%d", rt->pkt_size);
+av_dict_set(&opts, "pkt_size", buf, 0);
 
 return opts;
 }
diff --git a/libavformat/rtsp.h b/libavformat/rtsp.h
index 9dfbc5367..c38b90432 100644
--- a/libavformat/rtsp.h
+++ b/libavformat/rtsp.h
@@ -399,6 +399,7 @@ typedef struct RTSPState {
 
 char default_lang[4];
 int buffer_size;
+int pkt_size;
 
 const URLProtocol **protocols;
 } RTSPState;
-- 
2.17.1

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

Re: [libav-devel] [PATCH] rtsp: only break on parse_rtsp_message on error

2017-11-29 Thread Tristan Matthews
On Wed, Nov 29, 2017 at 3:14 PM, Martin Storsjö  wrote:
> On Wed, 29 Nov 2017, Tristan Matthews wrote:
>
>> Fix suggested by Luca Barbato.
>>
>> This was causing spurious EOFs when using -rtsp_transport udp, as
>> reported in https://bugzilla.libav.org/show_bug.cgi?id=1103
>> ---
>> libavformat/rtsp.c | 4 +++-
>> 1 file changed, 3 insertions(+), 1 deletion(-)
>>
>> diff --git a/libavformat/rtsp.c b/libavformat/rtsp.c
>> index 17a25a310..8bf9d9e3c 100644
>> --- a/libavformat/rtsp.c
>> +++ b/libavformat/rtsp.c
>> @@ -1998,7 +1998,9 @@ static int udp_read_packet(AVFormatContext *s,
>> RTSPStream **prtsp_st,
>> }
>> #if CONFIG_RTSP_DEMUXER
>> if (rt->rtsp_hd && p[0].revents & POLLIN) {
>> -return parse_rtsp_message(s);
>> +if ((ret = parse_rtsp_message(s)) < 0) {
>> +return ret;
>> +}
>> }
>> #endif
>> } else if (n == 0 && ++timeout_cnt >= MAX_TIMEOUTS) {
>> --
>> 2.15.0
>
>
> Looks good, I think. I wonder why nobody has run into this until now though.
>

I found a few similar looking issues when searching for "RTSP EOF".
Most people just reported that they'd "fixed" the issue by forcing
-rtsp_transport tcp.
___
libav-devel mailing list
libav-devel@libav.org
https://lists.libav.org/mailman/listinfo/libav-devel

[libav-devel] [PATCH] rtsp: only break on parse_rtsp_message on error

2017-11-29 Thread Tristan Matthews
Fix suggested by Luca Barbato.

This was causing spurious EOFs when using -rtsp_transport udp, as
reported in https://bugzilla.libav.org/show_bug.cgi?id=1103
---
 libavformat/rtsp.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/libavformat/rtsp.c b/libavformat/rtsp.c
index 17a25a310..8bf9d9e3c 100644
--- a/libavformat/rtsp.c
+++ b/libavformat/rtsp.c
@@ -1998,7 +1998,9 @@ static int udp_read_packet(AVFormatContext *s, RTSPStream 
**prtsp_st,
 }
 #if CONFIG_RTSP_DEMUXER
 if (rt->rtsp_hd && p[0].revents & POLLIN) {
-return parse_rtsp_message(s);
+if ((ret = parse_rtsp_message(s)) < 0) {
+return ret;
+}
 }
 #endif
 } else if (n == 0 && ++timeout_cnt >= MAX_TIMEOUTS) {
-- 
2.15.0

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

Re: [libav-devel] [PATCH] Canopus HQ/HQA decoder

2015-03-24 Thread Tristan Matthews
On Tue, Mar 24, 2015 at 4:09 PM, Tristan Matthews
 wrote:
> On Tue, Mar 24, 2015 at 3:03 PM, Derek Buitenhuis
>  wrote:
>> On 3/24/2015 6:53 PM, Luca Barbato wrote:
>>> No, it is exactly to keep the structure packed a little as I explained
>>> to Vittorio privately.
>>
>> So, micro-optimizations / ricing?
>>
>>> Diego (Flameeyes) explained in a number of blogpost why it is useful,
>>> sadly pahole is not available for mac.
>>
>> I can't much think how it is useful in any practical sense... link?
>> Google appears to have no knowledge of it.
>
> https://blog.flameeyes.eu/2008/03/some-words-about-global-variable

sorry, https://blog.flameeyes.eu/2008/03/some-words-about-global-variables
___
libav-devel mailing list
libav-devel@libav.org
https://lists.libav.org/mailman/listinfo/libav-devel


Re: [libav-devel] [PATCH] Canopus HQ/HQA decoder

2015-03-24 Thread Tristan Matthews
On Tue, Mar 24, 2015 at 3:03 PM, Derek Buitenhuis
 wrote:
> On 3/24/2015 6:53 PM, Luca Barbato wrote:
>> No, it is exactly to keep the structure packed a little as I explained
>> to Vittorio privately.
>
> So, micro-optimizations / ricing?
>
>> Diego (Flameeyes) explained in a number of blogpost why it is useful,
>> sadly pahole is not available for mac.
>
> I can't much think how it is useful in any practical sense... link?
> Google appears to have no knowledge of it.

https://blog.flameeyes.eu/2008/03/some-words-about-global-variable
https://blog.flameeyes.eu/2009/11/the-importance-of-opaque-types

-t
___
libav-devel mailing list
libav-devel@libav.org
https://lists.libav.org/mailman/listinfo/libav-devel


Re: [libav-devel] [PATCH] Canopus HQ/HQA decoder

2015-03-24 Thread Tristan Matthews
On Mon, Mar 23, 2015 at 8:40 AM, Vittorio Giovara
 wrote:
> On Sun, Mar 22, 2015 at 7:36 PM, Luca Barbato  wrote:
>>> +typedef struct HQContext {
>>> +AVCodecContext *avctx;
>>> +
>>> +VLC hq_ac_vlc;
>>> +VLC hqa_cbp_vlc;
>>> +DECLARE_ALIGNED(16, int16_t, block)[12][64];
>>> +} HQContext;
>>> +
>>> +typedef struct HQProfile {
>>> +int width, height;
>>> +int num_slices;
>>> +const uint8_t *perm_tab;
>>> +int tab_w, tab_h;
>>> +} HQProfile;
>>
>>
>> Pointers first, int after please.
>>
>
> Can you explain this in more details please?

I think he means for packing, see: http://www.catb.org/esr/structure-packing/

Best,
t
___
libav-devel mailing list
libav-devel@libav.org
https://lists.libav.org/mailman/listinfo/libav-devel


[libav-devel] [PATCH 1/1] srtpproto: fix option flag type

2014-12-16 Thread Tristan Matthews
---
 libavformat/srtpproto.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libavformat/srtpproto.c b/libavformat/srtpproto.c
index f9b94d7..1f818d7 100644
--- a/libavformat/srtpproto.c
+++ b/libavformat/srtpproto.c
@@ -42,8 +42,8 @@ typedef struct SRTPProtoContext {
 static const AVOption options[] = {
 { "srtp_out_suite", "", offsetof(SRTPProtoContext, out_suite), 
AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, E },
 { "srtp_out_params", "", offsetof(SRTPProtoContext, out_params), 
AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, E },
-{ "srtp_in_suite", "", offsetof(SRTPProtoContext, in_suite), 
AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, E },
-{ "srtp_in_params", "", offsetof(SRTPProtoContext, in_params), 
AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, E },
+{ "srtp_in_suite", "", offsetof(SRTPProtoContext, in_suite), 
AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, D },
+{ "srtp_in_params", "", offsetof(SRTPProtoContext, in_params), 
AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, D },
 { NULL }
 };
 
-- 
1.9.3

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


[libav-devel] [PATCH 1/1] v4l2: Use av_strerror

2014-11-05 Thread Tristan Matthews
---
 libavdevice/v4l2.c | 49 ++---
 1 file changed, 34 insertions(+), 15 deletions(-)

diff --git a/libavdevice/v4l2.c b/libavdevice/v4l2.c
index e210dc4..3439325 100644
--- a/libavdevice/v4l2.c
+++ b/libavdevice/v4l2.c
@@ -119,6 +119,7 @@ static int device_open(AVFormatContext *ctx)
 int fd;
 int res, err;
 int flags = O_RDWR;
+char errbuf[128];
 
 if (ctx->flags & AVFMT_FLAG_NONBLOCK) {
 flags |= O_NONBLOCK;
@@ -126,19 +127,21 @@ static int device_open(AVFormatContext *ctx)
 
 fd = avpriv_open(ctx->filename, flags);
 if (fd < 0) {
-err = errno;
+err = AVERROR(errno);
+av_strerror(err, errbuf, sizeof(errbuf));
 
 av_log(ctx, AV_LOG_ERROR, "Cannot open video device %s : %s\n",
-   ctx->filename, strerror(err));
+   ctx->filename, errbuf);
 
-return AVERROR(err);
+return err;
 }
 
 res = ioctl(fd, VIDIOC_QUERYCAP, &cap);
 if (res < 0) {
 err = errno;
+av_strerror(AVERROR(err), errbuf, sizeof(errbuf));
 av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_QUERYCAP): %s\n",
-   strerror(err));
+   errbuf);
 
 goto fail;
 }
@@ -401,7 +404,9 @@ static int mmap_init(AVFormatContext *ctx)
s->fd, buf.m.offset);
 
 if (s->buf_start[i] == MAP_FAILED) {
-av_log(ctx, AV_LOG_ERROR, "mmap: %s\n", strerror(errno));
+char errbuf[128];
+av_strerror(AVERROR(errno), errbuf, sizeof(errbuf));
+av_log(ctx, AV_LOG_ERROR, "mmap: %s\n", errbuf);
 
 return AVERROR(errno);
 }
@@ -423,6 +428,7 @@ static void mmap_release_buffer(void *opaque, uint8_t *data)
 int res, fd;
 struct buff_data *buf_descriptor = opaque;
 struct video_data *s = buf_descriptor->s;
+char errbuf[128];
 
 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
 buf.memory = V4L2_MEMORY_MMAP;
@@ -431,9 +437,11 @@ static void mmap_release_buffer(void *opaque, uint8_t 
*data)
 av_free(buf_descriptor);
 
 res = ioctl(fd, VIDIOC_QBUF, &buf);
-if (res < 0)
+if (res < 0) {
+av_strerror(AVERROR(errno), errbuf, sizeof(errbuf));
 av_log(NULL, AV_LOG_ERROR, "ioctl(VIDIOC_QBUF): %s\n",
-   strerror(errno));
+   errbuf);
+}
 avpriv_atomic_int_add_and_fetch(&s->buffers_queued, 1);
 }
 
@@ -457,13 +465,15 @@ static int mmap_read_frame(AVFormatContext *ctx, AVPacket 
*pkt)
 /* FIXME: Some special treatment might be needed in case of loss of 
signal... */
 while ((res = ioctl(s->fd, VIDIOC_DQBUF, &buf)) < 0 && (errno == EINTR));
 if (res < 0) {
+char errbuf[128];
 if (errno == EAGAIN) {
 pkt->size = 0;
 
 return AVERROR(EAGAIN);
 }
+av_strerror(AVERROR(errno), errbuf, sizeof(errbuf));
 av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_DQBUF): %s\n",
-   strerror(errno));
+   errbuf);
 
 return AVERROR(errno);
 }
@@ -542,7 +552,8 @@ static int mmap_start(AVFormatContext *ctx)
 {
 struct video_data *s = ctx->priv_data;
 enum v4l2_buf_type type;
-int i, res;
+int i, res, err;
+char errbuf[128];
 
 for (i = 0; i < s->buffers; i++) {
 struct v4l2_buffer buf = {
@@ -553,10 +564,12 @@ static int mmap_start(AVFormatContext *ctx)
 
 res = ioctl(s->fd, VIDIOC_QBUF, &buf);
 if (res < 0) {
+err = AVERROR(errno);
+av_strerror(err, errbuf, sizeof(errbuf));
 av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_QBUF): %s\n",
-   strerror(errno));
+   errbuf);
 
-return AVERROR(errno);
+return err;
 }
 }
 s->buffers_queued = s->buffers;
@@ -564,10 +577,12 @@ static int mmap_start(AVFormatContext *ctx)
 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
 res = ioctl(s->fd, VIDIOC_STREAMON, &type);
 if (res < 0) {
+err = AVERROR(errno);
+av_strerror(err, errbuf, sizeof(errbuf));
 av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_STREAMON): %s\n",
-   strerror(errno));
+   errbuf);
 
-return AVERROR(errno);
+return err;
 }
 
 return 0;
@@ -677,8 +692,10 @@ static int v4l2_set_parameters(AVFormatContext *s1)
 }
 } else {
 if (ioctl(s->fd, VIDIOC_G_PARM, &streamparm) != 0) {
+char errbuf[128];
+av_strerror(AVERROR(errno), errbuf, sizeof(errbuf));
 av_log(s1, AV_LOG_ERROR, "ioctl(VIDIOC_G_PARM): %s\n",
-   strerror(errno));
+   errbuf);
 return AVERROR(errno);
 }
 }
@@ -779,8 +796,10 @@ static int v4l2_read_header(AVFormatContext *s1)
"Querying the device for the current frame size\n");
 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
 if (ioctl(s->fd, VIDIOC_G_FMT, &fmt) < 0) {
+  

[libav-devel] [PATCH] flacdec: remove unused headers

2014-09-12 Thread Tristan Matthews
---
 libavcodec/flacdec.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/libavcodec/flacdec.c b/libavcodec/flacdec.c
index 9ca55cc..a475309 100644
--- a/libavcodec/flacdec.c
+++ b/libavcodec/flacdec.c
@@ -33,8 +33,6 @@
 
 #include 
 
-#include "libavutil/channel_layout.h"
-#include "libavutil/crc.h"
 #include "avcodec.h"
 #include "internal.h"
 #include "get_bits.h"
-- 
1.9.3

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


[libav-devel] [PATCH] tiffenc: fix packet size calculation

2014-06-13 Thread Tristan Matthews
---
 libavcodec/tiffenc.c | 8 +---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/libavcodec/tiffenc.c b/libavcodec/tiffenc.c
index ccfb07c..c94c7f4 100644
--- a/libavcodec/tiffenc.c
+++ b/libavcodec/tiffenc.c
@@ -218,6 +218,7 @@ static int encode_frame(AVCodecContext *avctx, AVPacket 
*pkt,
 int is_yuv = 0;
 uint8_t *yuv_line = NULL;
 int shift_h, shift_v;
+int packet_size;
 const AVPixFmtDescriptor *pfd;
 
 s->avctx = avctx;
@@ -288,10 +289,11 @@ static int encode_frame(AVCodecContext *avctx, AVPacket 
*pkt,
 
 strips = (s->height - 1) / s->rps + 1;
 
+packet_size = avctx->height * (avctx->width * s->bpp + 7 >> 3) * 2 +
+  avctx->height * 4 + FF_MIN_BUFFER_SIZE;
+
 if (!pkt->data &&
-(ret = av_new_packet(pkt,
- avctx->width * avctx->height * s->bpp * 2 +
- avctx->height * 4 + FF_MIN_BUFFER_SIZE)) < 0) {
+(ret = av_new_packet(pkt, packet_size)) < 0) {
 av_log(avctx, AV_LOG_ERROR, "Error getting output packet.\n");
 return ret;
 }
-- 
1.9.1

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


[libav-devel] [PATCH] tiffenc: fix packet size calculation

2014-06-13 Thread Tristan Matthews
---
 libavcodec/tiffenc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libavcodec/tiffenc.c b/libavcodec/tiffenc.c
index ccfb07c..c40f340 100644
--- a/libavcodec/tiffenc.c
+++ b/libavcodec/tiffenc.c
@@ -290,7 +290,7 @@ static int encode_frame(AVCodecContext *avctx, AVPacket 
*pkt,
 
 if (!pkt->data &&
 (ret = av_new_packet(pkt,
- avctx->width * avctx->height * s->bpp * 2 +
+ (avctx->width * avctx->height * s->bpp * 2) >> 3 +
  avctx->height * 4 + FF_MIN_BUFFER_SIZE)) < 0) {
 av_log(avctx, AV_LOG_ERROR, "Error getting output packet.\n");
 return ret;
-- 
1.9.1

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


[libav-devel] [PATCH] configure: fix enable-libopus help string

2014-05-14 Thread Tristan Matthews
---
 configure | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/configure b/configure
index 1e9a54c..9b73883 100755
--- a/configure
+++ b/configure
@@ -192,7 +192,7 @@ External library support:
   --enable-libopencore-amrwb enable AMR-WB decoding via libopencore-amrwb [no]
   --enable-libopencv   enable video filtering via libopencv [no]
   --enable-libopenjpeg enable JPEG 2000 de/encoding via OpenJPEG [no]
-  --enable-libopus enable Opus decoding via libopus [no]
+  --enable-libopus enable Opus de/encoding via libopus [no]
   --enable-libpulseenable Pulseaudio input via libpulse [no]
   --enable-librtmp enable RTMP[E] support via librtmp [no]
   --enable-libschroedinger enable Dirac de/encoding via libschroedinger [no]
-- 
1.9.0

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


[libav-devel] [PATCH] lavu: use unsigned for sample and channel counts

2014-01-31 Thread Tristan Matthews
---
 libavutil/samplefmt.c | 9 +
 libavutil/samplefmt.h | 3 ++-
 2 files changed, 7 insertions(+), 5 deletions(-)

diff --git a/libavutil/samplefmt.c b/libavutil/samplefmt.c
index 389f726..8361bcf 100644
--- a/libavutil/samplefmt.c
+++ b/libavutil/samplefmt.c
@@ -105,7 +105,8 @@ int av_sample_fmt_is_planar(enum AVSampleFormat sample_fmt)
  return sample_fmt_info[sample_fmt].planar;
 }
 
-int av_samples_get_buffer_size(int *linesize, int nb_channels, int nb_samples,
+int av_samples_get_buffer_size(int *linesize, unsigned nb_channels,
+   unsigned nb_samples,
enum AVSampleFormat sample_fmt, int align)
 {
 int line_size;
@@ -113,7 +114,7 @@ int av_samples_get_buffer_size(int *linesize, int 
nb_channels, int nb_samples,
 int planar  = av_sample_fmt_is_planar(sample_fmt);
 
 /* validate parameter ranges */
-if (!sample_size || nb_samples <= 0 || nb_channels <= 0)
+if (!sample_size || nb_samples == 0 || nb_channels == 0)
 return AVERROR(EINVAL);
 
 /* auto-select alignment if not specified */
@@ -123,8 +124,8 @@ int av_samples_get_buffer_size(int *linesize, int 
nb_channels, int nb_samples,
 }
 
 /* check for integer overflow */
-if (nb_channels > INT_MAX / align ||
-(int64_t)nb_channels * nb_samples > (INT_MAX - (align * nb_channels)) 
/ sample_size)
+if (nb_channels > UINT_MAX / align ||
+(uint64_t)nb_channels * nb_samples > (UINT_MAX - (align * 
nb_channels)) / sample_size)
 return AVERROR(EINVAL);
 
 line_size = planar ? FFALIGN(nb_samples * sample_size,   
align) :
diff --git a/libavutil/samplefmt.h b/libavutil/samplefmt.h
index 33cbded..10ae1df 100644
--- a/libavutil/samplefmt.h
+++ b/libavutil/samplefmt.h
@@ -138,7 +138,8 @@ int av_sample_fmt_is_planar(enum AVSampleFormat sample_fmt);
  * @param align buffer size alignment (0 = default, 1 = no alignment)
  * @return  required buffer size, or negative error code on failure
  */
-int av_samples_get_buffer_size(int *linesize, int nb_channels, int nb_samples,
+int av_samples_get_buffer_size(int *linesize, unsigned nb_channels,
+   unsigned nb_samples,
enum AVSampleFormat sample_fmt, int align);
 
 /**
-- 
1.8.5.3

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


Re: [libav-devel] [PATCH] samplefmt: avoid integer overflow in av_samples_get_buffer_size()

2014-01-30 Thread Tristan Matthews
On Thu, Jan 30, 2014 at 2:20 PM, Luca Barbato  wrote:
>
> On 30/01/14 20:11, Justin Ruggles wrote:
> > CC:libav-sta...@libav.org
> > ---
> >  libavutil/samplefmt.c | 2 ++
> >  1 file changed, 2 insertions(+)
> >
> > diff --git a/libavutil/samplefmt.c b/libavutil/samplefmt.c
> > index 389f726..bff6004 100644
> > --- a/libavutil/samplefmt.c
> > +++ b/libavutil/samplefmt.c
> > @@ -118,6 +118,8 @@ int av_samples_get_buffer_size(int *linesize, int 
> > nb_channels, int nb_samples,
> >
> >  /* auto-select alignment if not specified */
> >  if (!align) {
> > +if (nb_samples > INT_MAX - 31)
> > +return AVERROR(EINVAL);
> >  align = 1;
> >  nb_samples = FFALIGN(nb_samples, 32);
> >  }
> >
>
> Sounds safe.

In the long term, would it make sense for the nb_channels and
nb_samples arguments to be changed to unsigned (i.e. in new API)?
___
libav-devel mailing list
libav-devel@libav.org
https://lists.libav.org/mailman/listinfo/libav-devel


Re: [libav-devel] [PATCH v2] jack: use condition variable instead of semaphore

2013-12-06 Thread Tristan Matthews
On Fri, Dec 6, 2013 at 9:59 AM, Rémi Denis-Courmont  wrote:
> Le vendredi 6 décembre 2013, 09:28:00 Tristan Matthews a écrit :
>> > A condition variable MUST have some kind of state protected by its mutex.
>> > Without such state, there is NO meaning to the condition variable. If you
>> > do lock then wait then unlock with nothing in between them, then the use
>> > of a condition variable is wrong. Period.
>>
>> Then should it be (in the reader thread):
>> 1) Lock the mutex
>> 2) Check the read space
>> 3) If empty, wait on the condition variable
>> 4) Unlock the mutex
>>
>> Currently 1) and 2) are inverted.
>
> If the read space is protected by the mutex, yes. Otherwise, you should not be
> using a condition variable.

It's protected by atomic operations, so I'm guessing the answer will
again be "you should not be using a condition variable."

To recap for others, we need a wakeup mechanism to notify the reader
thread that packets are ready if it's waiting on an empty queue,
semaphores are the best solution, but they're broken on OS X.
Bug-Id: 312 called for condition variables, but if they're not
appropriate I'm open to other suggestions.

Best,
Tristan

-- 
Tristan Matthews
web: http://tristanswork.blogspot.com
___
libav-devel mailing list
libav-devel@libav.org
https://lists.libav.org/mailman/listinfo/libav-devel


Re: [libav-devel] [PATCH v2] jack: use condition variable instead of semaphore

2013-12-06 Thread Tristan Matthews
On Fri, Dec 6, 2013 at 8:16 AM, Rémi Denis-Courmont  wrote:
> Le lundi 2 décembre 2013, 16:38:55 Tristan Matthews a écrit :
>> On Sun, Dec 1, 2013 at 4:21 PM, Rémi Denis-Courmont  wrote:
>> > Le dimanche 1 décembre 2013, 16:15:22 Tristan Matthews a écrit :
>> >> jack_ringbuffers are used instead of AVFifoBuffers as they are safe for
>> >> lock-free use (in single-writer, single-reader scenarios).
>> >
>> > The use of condition variable without locked predicate/state makes as
>> > little sense (i.e. no) as in previous iterations IMO.
>>
>> In this version, the process callback is locking the mutex before
>> signaling (with try_lock), is that not adequate?
>
> This is irrelevant.
>
> A condition variable MUST have some kind of state protected by its mutex.
> Without such state, there is NO meaning to the condition variable. If you do
> lock then wait then unlock with nothing in between them, then the use of a
> condition variable is wrong. Period.

Then should it be (in the reader thread):
1) Lock the mutex
2) Check the read space
3) If empty, wait on the condition variable
4) Unlock the mutex

Currently 1) and 2) are inverted.

Best,
Tristan

-- 
Tristan Matthews
web: http://tristanswork.blogspot.com
___
libav-devel mailing list
libav-devel@libav.org
https://lists.libav.org/mailman/listinfo/libav-devel


Re: [libav-devel] [PATCH v2] jack: use condition variable instead of semaphore

2013-12-02 Thread Tristan Matthews
On Sun, Dec 1, 2013 at 4:21 PM, Rémi Denis-Courmont  wrote:
> Le dimanche 1 décembre 2013, 16:15:22 Tristan Matthews a écrit :
>> jack_ringbuffers are used instead of AVFifoBuffers as they are safe for
>> lock-free use (in single-writer, single-reader scenarios).
>
> The use of condition variable without locked predicate/state makes as little
> sense (i.e. no) as in previous iterations IMO.

In this version, the process callback is locking the mutex before
signaling (with try_lock),
is that not adequate? In any case, even if the reader misses a signal
because it is not yet waiting on the condition variable, it will catch
the next one. Moreover,
it will only start waiting if it finds the ringbuffer to be empty.

I agree that using a semaphore is better (since you avoid the above
missed signal problem), but that's the whole issue with
https://bugzilla.libav.org/show_bug.cgi?id=312
Could someone clarify what exactly is wrong with Mac OS X semaphores?
I've only found this so far:
http://dev.alopix.net/2012/10/os-x-dont-trust-posix-certificate.html

in which case, could this be more simply resolved by using a named semaphore?

Best,
Tristan

-- 
Tristan Matthews
web: http://tristanswork.blogspot.com
___
libav-devel mailing list
libav-devel@libav.org
https://lists.libav.org/mailman/listinfo/libav-devel


[libav-devel] [PATCH v2] jack: use condition variable instead of semaphore

2013-12-01 Thread Tristan Matthews
jack_ringbuffers are used instead of AVFifoBuffers as they are safe for
lock-free use (in single-writer, single-reader scenarios).

Bug-Id: 312
---
 libavdevice/jack_audio.c | 118 +--
 1 file changed, 74 insertions(+), 44 deletions(-)

diff --git a/libavdevice/jack_audio.c b/libavdevice/jack_audio.c
index c261514..53f75a1 100644
--- a/libavdevice/jack_audio.c
+++ b/libavdevice/jack_audio.c
@@ -21,11 +21,11 @@
  */
 
 #include "config.h"
-#include 
+#include 
 #include 
+#include 
 
 #include "libavutil/log.h"
-#include "libavutil/fifo.h"
 #include "libavutil/opt.h"
 #include "libavutil/time.h"
 #include "libavcodec/avcodec.h"
@@ -34,22 +34,23 @@
 #include "timefilter.h"
 
 /**
- * Size of the internal FIFO buffers as a number of audio packets
+ * Size of the internal ringbuffers as a number of audio packets
  */
-#define FIFO_PACKETS_NUM 16
+#define RING_PACKETS_NUM 16
 
 typedef struct {
 AVClass*class;
 jack_client_t * client;
 int activated;
-sem_t   packet_count;
+pthread_mutex_t read_lock;
+pthread_cond_t  packet_ready;
 jack_nframes_t  sample_rate;
 jack_nframes_t  buffer_size;
 jack_port_t **  ports;
 int nports;
 TimeFilter *timefilter;
-AVFifoBuffer *  new_pkts;
-AVFifoBuffer *  filled_pkts;
+jack_ringbuffer_t *new_pkts;
+jack_ringbuffer_t *filled_pkts;
 int pkt_xrun;
 int jack_xrun;
 } JackData;
@@ -79,13 +80,14 @@ static int process_callback(jack_nframes_t nframes, void 
*arg)
   self->buffer_size);
 
 /* Check if an empty packet is available, and if there's enough space to 
send it back once filled */
-if ((av_fifo_size(self->new_pkts) < sizeof(pkt)) || 
(av_fifo_space(self->filled_pkts) < sizeof(pkt))) {
+if ((jack_ringbuffer_read_space(self->new_pkts) < sizeof(pkt)) ||
+(jack_ringbuffer_write_space(self->filled_pkts) < sizeof(pkt))) {
 self->pkt_xrun = 1;
 return 0;
 }
 
 /* Retrieve empty (but allocated) packet */
-av_fifo_generic_read(self->new_pkts, &pkt, sizeof(pkt), NULL);
+jack_ringbuffer_read(self->new_pkts, (char *) &pkt, sizeof(pkt));
 
 pkt_data  = (float *) pkt.data;
 latency   = 0;
@@ -107,9 +109,13 @@ static int process_callback(jack_nframes_t nframes, void 
*arg)
 /* Timestamp the packet with the cycle start time minus the average 
latency */
 pkt.pts = (cycle_time - (double) latency / (self->nports * 
self->sample_rate)) * 100.0;
 
-/* Send the now filled packet back, and increase packet counter */
-av_fifo_generic_write(self->filled_pkts, &pkt, sizeof(pkt), NULL);
-sem_post(&self->packet_count);
+/* Send the now filled packet back, and signal that it's ready */
+jack_ringbuffer_write(self->filled_pkts, (char *) &pkt, sizeof(pkt));
+
+if (pthread_mutex_trylock(&self->read_lock) == 0) {
+pthread_cond_signal(&self->packet_ready);
+pthread_mutex_unlock(&self->read_lock);
+}
 
 return 0;
 }
@@ -136,12 +142,12 @@ static int supply_new_packets(JackData *self, 
AVFormatContext *context)
 /* Supply the process callback with new empty packets, by filling the new
  * packets FIFO buffer with as many packets as possible. process_callback()
  * can't do this by itself, because it can't allocate memory in realtime. 
*/
-while (av_fifo_space(self->new_pkts) >= sizeof(pkt)) {
+while (jack_ringbuffer_write_space(self->new_pkts) >= sizeof(pkt)) {
 if ((test = av_new_packet(&pkt, pkt_size)) < 0) {
 av_log(context, AV_LOG_ERROR, "Could not create packet of size 
%d\n", pkt_size);
 return test;
 }
-av_fifo_generic_write(self->new_pkts, &pkt, sizeof(pkt), NULL);
+jack_ringbuffer_write(self->new_pkts, (char *) &pkt, sizeof(pkt));
 }
 return 0;
 }
@@ -160,7 +166,8 @@ static int start_jack(AVFormatContext *context)
 return AVERROR(EIO);
 }
 
-sem_init(&self->packet_count, 0, 0);
+pthread_mutex_init(&self->read_lock, NULL);
+pthread_cond_init(&self->packet_ready, NULL);
 
 self->sample_rate = jack_get_sample_rate(self->client);
 self->ports   = av_malloc(self->nports * sizeof(*self->ports));
@@ -181,11 +188,6 @@ static int start_jack(AVFormatContext *context)
 }
 }
 
-/* Register JACK callbacks */
-jack_set_process_callback(self->client, process_callback, self);
-jack_on_shutdown(self->client, shutdown_callback, self);
-jack_set_xrun_callback(self->client, xrun_callback, self);
-
 /* Create time filter */
 period= (double) self->buffer_size / self->sample_rate;
 o = 2 * M_PI * 1.5 * period; /// bandwidth: 1.5Hz
@@ -195,27 +197,45 @@ static int start_jack(AVFormatContext *context)
 return AVERROR(ENOMEM);
 }
 
-/* Create FIFO buffers */
-self->filled_pkts = av_fifo_allo

Re: [libav-devel] [PATCH] jack: use pthread_cond_t instead of semaphore

2013-11-25 Thread Tristan Matthews
On Mon, Nov 25, 2013 at 5:22 AM, Rémi Denis-Courmont  wrote:
> On Sun, 24 Nov 2013 19:15:09 -0500, Tristan Matthews
>  wrote:
>> Fixes https://bugzilla.libav.org/show_bug.cgi?id=312
>> ---
>>  libavdevice/jack_audio.c | 55
>>  +++-
>>  1 file changed, 40 insertions(+), 15 deletions(-)
>>
>> diff --git a/libavdevice/jack_audio.c b/libavdevice/jack_audio.c
>> index c261514..ef6e0fb 100644
>> --- a/libavdevice/jack_audio.c
>> +++ b/libavdevice/jack_audio.c
>> @@ -21,7 +21,7 @@
>>   */
>>
>>  #include "config.h"
>> -#include 
>> +#include 
>>  #include 
>>
>>  #include "libavutil/log.h"
>> @@ -42,7 +42,8 @@ typedef struct {
>>  AVClass*class;
>>  jack_client_t * client;
>>  int activated;
>> -sem_t   packet_count;
>> +pthread_mutex_t pkt_mutex;
>> +pthread_cond_t  pkt_cond;
>>  jack_nframes_t  sample_rate;
>>  jack_nframes_t  buffer_size;
>>  jack_port_t **  ports;
>> @@ -107,9 +108,9 @@ static int process_callback(jack_nframes_t nframes,
>> void *arg)
>>  /* Timestamp the packet with the cycle start time minus the average
>>  latency */
>>  pkt.pts = (cycle_time - (double) latency / (self->nports *
>>  self->sample_rate)) * 100.0;
>>
>> -/* Send the now filled packet back, and increase packet counter */
>> +/* Send the now filled packet back, and signal that it's ready */
>>  av_fifo_generic_write(self->filled_pkts, &pkt, sizeof(pkt), NULL);
>> -sem_post(&self->packet_count);
>> +pthread_cond_signal(&self->pkt_cond);
>
> Signalling a condition variable without any mutex operation in the
> vicinity raises both of my eyebrows.

Yes, from the documentation you _can_ signal without locking but you
won't have "predictable
scheduling behaviour." I'm not sure how serious that is in a
single-writer, single-reader situation
like this one.
I can't lock the mutex in the process callback because it's not
real-time safe, in theory I could
try_lock but then how should failure to lock be handled?

>
>>
>>  return 0;
>>  }
>> @@ -160,7 +161,8 @@ static int start_jack(AVFormatContext *context)
>>  return AVERROR(EIO);
>>  }
>>
>> -sem_init(&self->packet_count, 0, 0);
>> +pthread_mutex_init(&self->pkt_mutex, NULL);
>> +pthread_cond_init(&self->pkt_cond, NULL);
>>
>>  self->sample_rate = jack_get_sample_rate(self->client);
>>  self->ports   = av_malloc(self->nports * sizeof(*self->ports));
>> @@ -225,7 +227,8 @@ static void stop_jack(JackData *self)
>>  jack_deactivate(self->client);
>>  jack_client_close(self->client);
>>  }
>> -sem_destroy(&self->packet_count);
>> +pthread_cond_destroy(&self->pkt_cond);
>> +pthread_mutex_destroy(&self->pkt_mutex);
>>  free_pkt_fifo(self->new_pkts);
>>  free_pkt_fifo(self->filled_pkts);
>>  av_freep(&self->ports);
>> @@ -284,18 +287,40 @@ static int audio_read_packet(AVFormatContext
>> *context, AVPacket *pkt)
>>
>>  /* Wait for a packet coming back from process_callback(), if one
>>  isn't available yet */
>>  timeout.tv_sec = av_gettime() / 100 + 2;
>> -if (sem_timedwait(&self->packet_count, &timeout)) {
>> -if (errno == ETIMEDOUT) {
>> -av_log(context, AV_LOG_ERROR,
>> -   "Input error: timed out when waiting for JACK
> process
>> callback output\n");
>> -} else {
>> -av_log(context, AV_LOG_ERROR, "Error while waiting for
> audio
>> packet: %s\n",
>> +
>> +/* Only wait if there's nothing to read yet */
>> +if (!av_fifo_size(self->filled_pkts)) {
>> +
>> +if (pthread_mutex_lock(&self->pkt_mutex)) {
>
> Cleanly handling pthread_mutex_lock error is _useless_. If that function
> does fail, the code is _already_ in undefined land(*). So, IMHO, aborting
> the process is the only reasonable thing to do.
>
> (*) There is one exception: if the mutex is error-checking *and* already
> locked by the calling thread, then EDEADLK will be returned.
>
>> +av_log(context, AV_LOG_ERROR, "Error while trying to lock
>> mutex: %s\n",
>> strerror(errno));
>> +return AVERRO

Re: [libav-devel] [PATCH] jack: use pthread_cond_t instead of semaphore

2013-11-25 Thread Tristan Matthews
On Mon, Nov 25, 2013 at 4:59 AM, Luca Barbato  wrote:
> On 25/11/13 01:15, Tristan Matthews wrote:
>> Fixes https://bugzilla.libav.org/show_bug.cgi?id=312
>
> use
>
> Bug-Id: 312
>
> Instead =)
>> ---
>>  libavdevice/jack_audio.c | 55 
>> +++-
>>  1 file changed, 40 insertions(+), 15 deletions(-)
>>
>
> Did you test it? I don't have jack around but:

yes (linux-only though).

>
> - You are accessing the fifo outside the mutex.

I was wondering about this. The original libavdevice/jack_audio.c
implementation uses
libav fifos which do not have memory barriers (though there are
comments mentioning them!)
It might be better to use the jackringbuffer structure (that jack
provides), which is a lock-free
ring buffer that does use atomic ops, but I didn't want to change too
many things at once.

What do you think?

>
> - Always save errno and forward it.
>
> The rest looks promising.

Thanks for the fast review.

>
> lu
>
>
>
> ___
> libav-devel mailing list
> libav-devel@libav.org
> https://lists.libav.org/mailman/listinfo/libav-devel



-- 
Tristan Matthews
web: http://tristanswork.blogspot.com
___
libav-devel mailing list
libav-devel@libav.org
https://lists.libav.org/mailman/listinfo/libav-devel


[libav-devel] [PATCH] jack: use pthread_cond_t instead of semaphore

2013-11-24 Thread Tristan Matthews
Fixes https://bugzilla.libav.org/show_bug.cgi?id=312
---
 libavdevice/jack_audio.c | 55 +++-
 1 file changed, 40 insertions(+), 15 deletions(-)

diff --git a/libavdevice/jack_audio.c b/libavdevice/jack_audio.c
index c261514..ef6e0fb 100644
--- a/libavdevice/jack_audio.c
+++ b/libavdevice/jack_audio.c
@@ -21,7 +21,7 @@
  */
 
 #include "config.h"
-#include 
+#include 
 #include 
 
 #include "libavutil/log.h"
@@ -42,7 +42,8 @@ typedef struct {
 AVClass*class;
 jack_client_t * client;
 int activated;
-sem_t   packet_count;
+pthread_mutex_t pkt_mutex;
+pthread_cond_t  pkt_cond;
 jack_nframes_t  sample_rate;
 jack_nframes_t  buffer_size;
 jack_port_t **  ports;
@@ -107,9 +108,9 @@ static int process_callback(jack_nframes_t nframes, void 
*arg)
 /* Timestamp the packet with the cycle start time minus the average 
latency */
 pkt.pts = (cycle_time - (double) latency / (self->nports * 
self->sample_rate)) * 100.0;
 
-/* Send the now filled packet back, and increase packet counter */
+/* Send the now filled packet back, and signal that it's ready */
 av_fifo_generic_write(self->filled_pkts, &pkt, sizeof(pkt), NULL);
-sem_post(&self->packet_count);
+pthread_cond_signal(&self->pkt_cond);
 
 return 0;
 }
@@ -160,7 +161,8 @@ static int start_jack(AVFormatContext *context)
 return AVERROR(EIO);
 }
 
-sem_init(&self->packet_count, 0, 0);
+pthread_mutex_init(&self->pkt_mutex, NULL);
+pthread_cond_init(&self->pkt_cond, NULL);
 
 self->sample_rate = jack_get_sample_rate(self->client);
 self->ports   = av_malloc(self->nports * sizeof(*self->ports));
@@ -225,7 +227,8 @@ static void stop_jack(JackData *self)
 jack_deactivate(self->client);
 jack_client_close(self->client);
 }
-sem_destroy(&self->packet_count);
+pthread_cond_destroy(&self->pkt_cond);
+pthread_mutex_destroy(&self->pkt_mutex);
 free_pkt_fifo(self->new_pkts);
 free_pkt_fifo(self->filled_pkts);
 av_freep(&self->ports);
@@ -284,18 +287,40 @@ static int audio_read_packet(AVFormatContext *context, 
AVPacket *pkt)
 
 /* Wait for a packet coming back from process_callback(), if one isn't 
available yet */
 timeout.tv_sec = av_gettime() / 100 + 2;
-if (sem_timedwait(&self->packet_count, &timeout)) {
-if (errno == ETIMEDOUT) {
-av_log(context, AV_LOG_ERROR,
-   "Input error: timed out when waiting for JACK process 
callback output\n");
-} else {
-av_log(context, AV_LOG_ERROR, "Error while waiting for audio 
packet: %s\n",
+
+/* Only wait if there's nothing to read yet */
+if (!av_fifo_size(self->filled_pkts)) {
+
+if (pthread_mutex_lock(&self->pkt_mutex)) {
+av_log(context, AV_LOG_ERROR, "Error while trying to lock mutex: 
%s\n",
strerror(errno));
+return AVERROR(EIO);
 }
-if (!self->client)
-av_log(context, AV_LOG_ERROR, "Input error: JACK server is 
gone\n");
 
-return AVERROR(EIO);
+if (pthread_cond_timedwait(&self->pkt_cond, &self->pkt_mutex, 
&timeout)) {
+if (errno == ETIMEDOUT) {
+av_log(context, AV_LOG_ERROR,
+   "Input error: timed out when waiting for JACK process 
callback output\n");
+} else {
+av_log(context, AV_LOG_ERROR, "Error while waiting for audio 
packet: %s\n",
+   strerror(errno));
+}
+if (!self->client)
+av_log(context, AV_LOG_ERROR, "Input error: JACK server is 
gone\n");
+
+if (pthread_mutex_unlock(&self->pkt_mutex)) {
+av_log(context, AV_LOG_ERROR, "Error while trying to unlock 
mutex: %s\n",
+   strerror(errno));
+}
+
+return AVERROR(EIO);
+}
+
+if (pthread_mutex_unlock(&self->pkt_mutex)) {
+av_log(context, AV_LOG_ERROR, "Error while trying to unlock mutex: 
%s\n",
+   strerror(errno));
+return AVERROR(EIO);
+}
 }
 
 if (self->pkt_xrun) {
-- 
1.8.1.2

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