Re: [FFmpeg-devel] [PATCH] avformat: Add Pro-MPEG CoP #3-R2 FEC protocol

2016-11-13 Thread Michael Niedermayer
On Thu, Jun 02, 2016 at 04:28:13PM +0200, Vlad Tarca wrote:
> Pro-MPEG Code of Practice #3 release 2 forward error correction for 
> rtp_mpegts streams
> 
> Signed-off-by: Vlad Tarca 
> ---
>  Changelog   |   1 +
>  doc/general.texi|   1 +
>  doc/protocols.texi  |  35 
>  libavformat/Makefile|   1 +
>  libavformat/prompeg.c   | 481 
> 
>  libavformat/protocols.c |   1 +
>  libavformat/rtpproto.c  |  61 +-
>  7 files changed, 578 insertions(+), 3 deletions(-)
>  create mode 100644 libavformat/prompeg.c

applied

thx

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

While the State exists there can be no freedom; when there is freedom there
will be no State. -- Vladimir Lenin


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


[FFmpeg-devel] [PATCH] avformat: Add Pro-MPEG CoP #3-R2 FEC protocol

2016-06-02 Thread Vlad Tarca
Pro-MPEG Code of Practice #3 release 2 forward error correction for rtp_mpegts 
streams

Signed-off-by: Vlad Tarca 
---
 Changelog   |   1 +
 doc/general.texi|   1 +
 doc/protocols.texi  |  35 
 libavformat/Makefile|   1 +
 libavformat/prompeg.c   | 481 
 libavformat/protocols.c |   1 +
 libavformat/rtpproto.c  |  61 +-
 7 files changed, 578 insertions(+), 3 deletions(-)
 create mode 100644 libavformat/prompeg.c

diff --git a/Changelog b/Changelog
index 697b430..34bc23a 100644
--- a/Changelog
+++ b/Changelog
@@ -37,6 +37,7 @@ version :
 - Direct Stream Transfer (DST) decoder
 - loudnorm filter
 - MTAF demuxer and decoder
+- Pro-MPEG CoP #3-R2 FEC protocol
 
 version 3.0:
 - Common Encryption (CENC) MP4 encoding and decoding support
diff --git a/doc/general.texi b/doc/general.texi
index 2d3dd0b..80a434a 100644
--- a/doc/general.texi
+++ b/doc/general.texi
@@ -1126,6 +1126,7 @@ performance on systems without hardware floating point 
support).
 @item MMSH @tab X
 @item MMST @tab X
 @item pipe @tab X
+@item Pro-MPEG FEC @tab X
 @item RTMP @tab X
 @item RTMPE@tab X
 @item RTMPS@tab X
diff --git a/doc/protocols.texi b/doc/protocols.texi
index a9c9d0c..875fdac 100644
--- a/doc/protocols.texi
+++ b/doc/protocols.texi
@@ -513,6 +513,41 @@ time, which is valuable if data transmission is slow.
 Note that some formats (typically MOV), require the output protocol to
 be seekable, so they will fail with the pipe output protocol.
 
+@section prompeg
+
+Pro-MPEG Code of Practice #3 Release 2 FEC protocol.
+
+The Pro-MPEG CoP#3 FEC is a 2D parity-check forward error correction mechanism
+for MPEG-2 Transport Streams sent over RTP.
+
+This protocol must be used in conjunction with the @code{rtp_mpegts} muxer and
+the @code{rtp} protocol.
+
+The required syntax is:
+@example
+-f rtp_mpegts -fec prompeg=@var{option}=@var{val}... 
rtp://@var{hostname}:@var{port}
+@end example
+
+The destination UDP ports are @code{port + 2} for the column FEC stream
+and @code{port + 4} for the row FEC stream.
+
+This protocol accepts the following options:
+@table @option
+
+@item l=@var{n}
+The number of columns (4-20, LxD <= 100)
+
+@item d=@var{n}
+The number of rows (4-20, LxD <= 100)
+
+@end table
+
+Example usage:
+
+@example
+-f rtp_mpegts -fec prompeg=l=8:d=4 rtp://@var{hostname}:@var{port}
+@end example
+
 @section rtmp
 
 Real-Time Messaging Protocol.
diff --git a/libavformat/Makefile b/libavformat/Makefile
index 6684ead..90d7587 100644
--- a/libavformat/Makefile
+++ b/libavformat/Makefile
@@ -547,6 +547,7 @@ OBJS-$(CONFIG_MD5_PROTOCOL)  += md5proto.o
 OBJS-$(CONFIG_MMSH_PROTOCOL) += mmsh.o mms.o asf.o
 OBJS-$(CONFIG_MMST_PROTOCOL) += mmst.o mms.o asf.o
 OBJS-$(CONFIG_PIPE_PROTOCOL) += file.o
+OBJS-$(CONFIG_PROMPEG_PROTOCOL)  += prompeg.o
 OBJS-$(CONFIG_RTMP_PROTOCOL) += rtmpproto.o rtmppkt.o
 OBJS-$(CONFIG_RTMPE_PROTOCOL)+= rtmpproto.o rtmppkt.o
 OBJS-$(CONFIG_RTMPS_PROTOCOL)+= rtmpproto.o rtmppkt.o
diff --git a/libavformat/prompeg.c b/libavformat/prompeg.c
new file mode 100644
index 000..cc1baa4
--- /dev/null
+++ b/libavformat/prompeg.c
@@ -0,0 +1,481 @@
+/*
+ * Pro-MPEG Code of Practice #3 Release 2 FEC
+ * Copyright (c) 2016 Mobibase, France (http://www.mobibase.com)
+ *
+ * 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
+ */
+
+/**
+ * @file
+ * Pro-MPEG Code of Practice #3 Release 2 FEC protocol
+ * @author Vlad Tarca 
+ */
+
+/*
+ * Reminder:
+
+ [RFC 2733] FEC Packet Structure
+
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   | RTP Header|
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   | FEC Header|
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   | FEC Payload   |
+   |   |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+
+ [RFC 3550] RTP 

Re: [FFmpeg-devel] [PATCH] avformat: Add Pro-MPEG CoP #3-R2 FEC protocol

2016-06-02 Thread Vlad Tarca
> also why are some called _size and some _len ?

I will use length_recovery as it's named exactly like that in the code of
practice and use better names for the rest.
The size check will also take into account UINT16_MAX and not INT_MAX since
the recovery field is only 16-bit.

> -ret = ffurl_write(hd, buf, size);
> +if ((ret = ffurl_write(hd, buf, size)) < 0) {
> +goto end;
> +}
> +
> +if (s->fec_hd && !RTP_PT_IS_RTCP(buf[1])) {
> +if ((ret_fec = ffurl_write(s->fec_hd, buf, size)) < 0) {
> +av_log(h, AV_LOG_ERROR, "Failed to send FEC\n");
> +ret = ret_fec;
> +}
> +}
> +
> +end:
>  return ret;

> the goto isnt needed, a direct return can be used
> also is ret_fec needed and cant ret be used directly ?

The reasoning here was that rtp_write() should return the result of the RTP
write operation on success, and not that of the FEC write.
If there's a better way let me know and I will implement it.

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


Re: [FFmpeg-devel] [PATCH] avformat: Add Pro-MPEG CoP #3-R2 FEC protocol

2016-06-01 Thread Michael Niedermayer
On Wed, Jun 01, 2016 at 11:19:38AM +0200, Vlad Tarca wrote:
> Pro-MPEG Code of Practice #3 release 2 forward error correction for 
> rtp_mpegts streams
> 
> Fixes:
> 
> [prompeg.c]
> - proper RTP size check to fit the largest buffer
> - UDP port overflow check
> - replaced ffurl_close calls with ffurl_closep
> [rtpproto.c]
> - removed context fec flag and used fec_hd directly
> - moved fec_hd open outside the retry loop as it doesn't set any specific 
> local ports
> - replaced ffurl_close call with ffurl_closep
> 
> Signed-off-by: Vlad Tarca 

please provide a commit message that works for the commit, not one
that lists th differences to the last patch
(as only the final one is commited that would be confusing)


[...]

> +static void xor_fast(const uint8_t *in1, const uint8_t *in2, uint8_t *out, 
> int size) {
> +int i, n, s;
> +
> +#if HAVE_FAST_64BIT
> +uint64_t v1, v2;
> +
> +n = size / sizeof (uint64_t);
> +s = n * sizeof (uint64_t);
> +
> +for (i = 0; i < n; i++) {
> +v1 = AV_RN64A(in1);
> +v2 = AV_RN64A(in2);
> +AV_WN64A(out, v1 ^ v2);
> +in1 += 8;
> +in2 += 8;
> +out += 8;
> +}
> +#else
> +uint32_t v1, v2;
> +
> +n = size / sizeof (uint32_t);
> +s = n * sizeof (uint32_t);
> +
> +for (i = 0; i < n; i++) {
> +v1 = AV_RN32A(in1);
> +v2 = AV_RN32A(in2);
> +AV_WN32A(out, v1 ^ v2);
> +in1 += 4;
> +in2 += 4;
> +out += 4;
> +}
> +#endif
> +

> +if (s == size)
> +return;

is it faster with this check ?
iam asking because the check doesnt change the outcome in any way


[...]

> +static int prompeg_open(URLContext *h, const char *uri, int flags) {
> +PrompegContext *s = h->priv_data;
> +AVDictionary *udp_opts = NULL;
> +int rtp_port;
> +char hostname[256];
> +char buf[1024];
> +
> +s->fec_col_hd = NULL;
> +s->fec_row_hd = NULL;
> +
> +if (s->l * s->d > 100) {
> +av_log(h, AV_LOG_ERROR, "L * D must be <= 100\n");
> +return AVERROR(EINVAL);
> +}
> +
> +av_url_split(NULL, 0, NULL, 0, hostname, sizeof (hostname), _port,
> +NULL, 0, uri);
> +
> +if (rtp_port < 1 || rtp_port > 65531) {
> +av_log(h, AV_LOG_ERROR, "Invalid RTP base port %d\n", rtp_port);
> +return AVERROR(EINVAL);
> +}
> +
> +if (s->ttl > 0) {
> +snprintf(buf, sizeof (buf), "%d", s->ttl);
> +av_dict_set(_opts, "ttl", buf, 0);
> +}
> +
> +ff_url_join(buf, sizeof (buf), "udp", NULL, hostname, rtp_port + 2, 
> NULL);
> +if (ffurl_open_whitelist(>fec_col_hd, buf, flags, 
> >interrupt_callback,
> +_opts, h->protocol_whitelist, h->protocol_blacklist, h) < 0)
> +goto fail;
> +ff_url_join(buf, sizeof (buf), "udp", NULL, hostname, rtp_port + 4, 
> NULL);
> +if (ffurl_open_whitelist(>fec_row_hd, buf, flags, 
> >interrupt_callback,
> +_opts, h->protocol_whitelist, h->protocol_blacklist, h) < 0)
> +goto fail;
> +
> +h->max_packet_size = s->fec_col_hd->max_packet_size;
> +s->init = 1;
> +
> +av_dict_free(_opts);
> +av_log(h, AV_LOG_INFO, "ProMPEG CoP#3-R2 FEC L=%d D=%d\n", s->l, s->d);
> +return 0;
> +
> +fail:
> +ffurl_closep(>fec_col_hd);
> +ffurl_closep(>fec_row_hd);
> +av_dict_free(_opts);
> +return AVERROR(EIO);
> +}
> +
> +static int prompeg_init(URLContext *h, const uint8_t *buf, int size) {
> +PrompegContext *s = h->priv_data;
> +uint32_t seed;
> +int bitstring_len, rtp_buf_len;
> +int i;
> +
> +s->fec_buf = NULL;
> +s->rtp_buf = NULL;
> +
> +if (size < 12 || size >= INT_MAX - 16) {
> +av_log(h, AV_LOG_ERROR, "Invalid RTP packet size\n");
> +return AVERROR_INVALIDDATA;
> +}
> +
> +s->packet_idx = 0;
> +s->packet_idx_max = s->l * s->d;
> +s->packet_size = size;
> +s->recovery_len = size - 12;
> +rtp_buf_len = 28 + s->recovery_len; // 12 + 16: RTP + FEC headers

> +s->rtp_buf_size = rtp_buf_len * sizeof (uint8_t);
> +bitstring_len = 8 + s->recovery_len; // 8: P, X, CC, M, PT, SN, TS
> +s->bitstring_size = bitstring_len * sizeof (uint8_t);

sizeof (uint8_t) is always 1, the multiplications arent needed
also why are some called _size and some _len ?


[...]
> @@ -412,6 +441,14 @@ static int rtp_open(URLContext *h, const char *uri, int 
> flags)
>  break;
>  }
>  
> +s->fec_hd = NULL;
> +if (fec_protocol) {
> +ff_url_join(buf, sizeof(buf), fec_protocol, NULL, hostname, 
> rtp_port, NULL);

> +if (ffurl_open_whitelist(>fec_hd, buf, flags, 
> >interrupt_callback,
> + _opts, h->protocol_whitelist, 
> h->protocol_blacklist, h) < 0)
> +goto fail;

something is wrong with the indention here


[...]
> @@ -474,7 +518,7 @@ static int rtp_read(URLContext *h, uint8_t *buf, int size)
>  static int rtp_write(URLContext *h, const uint8_t *buf, int 

[FFmpeg-devel] [PATCH] avformat: Add Pro-MPEG CoP #3-R2 FEC protocol

2016-06-01 Thread Vlad Tarca
Pro-MPEG Code of Practice #3 release 2 forward error correction for rtp_mpegts 
streams

Fixes:

[prompeg.c]
- proper RTP size check to fit the largest buffer
- UDP port overflow check
- replaced ffurl_close calls with ffurl_closep
[rtpproto.c]
- removed context fec flag and used fec_hd directly
- moved fec_hd open outside the retry loop as it doesn't set any specific local 
ports
- replaced ffurl_close call with ffurl_closep

Signed-off-by: Vlad Tarca 
---
 Changelog   |   1 +
 doc/general.texi|   1 +
 doc/protocols.texi  |  35 
 libavformat/Makefile|   1 +
 libavformat/prompeg.c   | 487 
 libavformat/protocols.c |   1 +
 libavformat/rtpproto.c  |  62 +-
 7 files changed, 585 insertions(+), 3 deletions(-)
 create mode 100644 libavformat/prompeg.c

diff --git a/Changelog b/Changelog
index 697b430..34bc23a 100644
--- a/Changelog
+++ b/Changelog
@@ -37,6 +37,7 @@ version :
 - Direct Stream Transfer (DST) decoder
 - loudnorm filter
 - MTAF demuxer and decoder
+- Pro-MPEG CoP #3-R2 FEC protocol
 
 version 3.0:
 - Common Encryption (CENC) MP4 encoding and decoding support
diff --git a/doc/general.texi b/doc/general.texi
index 2d3dd0b..80a434a 100644
--- a/doc/general.texi
+++ b/doc/general.texi
@@ -1126,6 +1126,7 @@ performance on systems without hardware floating point 
support).
 @item MMSH @tab X
 @item MMST @tab X
 @item pipe @tab X
+@item Pro-MPEG FEC @tab X
 @item RTMP @tab X
 @item RTMPE@tab X
 @item RTMPS@tab X
diff --git a/doc/protocols.texi b/doc/protocols.texi
index a9c9d0c..875fdac 100644
--- a/doc/protocols.texi
+++ b/doc/protocols.texi
@@ -513,6 +513,41 @@ time, which is valuable if data transmission is slow.
 Note that some formats (typically MOV), require the output protocol to
 be seekable, so they will fail with the pipe output protocol.
 
+@section prompeg
+
+Pro-MPEG Code of Practice #3 Release 2 FEC protocol.
+
+The Pro-MPEG CoP#3 FEC is a 2D parity-check forward error correction mechanism
+for MPEG-2 Transport Streams sent over RTP.
+
+This protocol must be used in conjunction with the @code{rtp_mpegts} muxer and
+the @code{rtp} protocol.
+
+The required syntax is:
+@example
+-f rtp_mpegts -fec prompeg=@var{option}=@var{val}... 
rtp://@var{hostname}:@var{port}
+@end example
+
+The destination UDP ports are @code{port + 2} for the column FEC stream
+and @code{port + 4} for the row FEC stream.
+
+This protocol accepts the following options:
+@table @option
+
+@item l=@var{n}
+The number of columns (4-20, LxD <= 100)
+
+@item d=@var{n}
+The number of rows (4-20, LxD <= 100)
+
+@end table
+
+Example usage:
+
+@example
+-f rtp_mpegts -fec prompeg=l=8:d=4 rtp://@var{hostname}:@var{port}
+@end example
+
 @section rtmp
 
 Real-Time Messaging Protocol.
diff --git a/libavformat/Makefile b/libavformat/Makefile
index 6684ead..90d7587 100644
--- a/libavformat/Makefile
+++ b/libavformat/Makefile
@@ -547,6 +547,7 @@ OBJS-$(CONFIG_MD5_PROTOCOL)  += md5proto.o
 OBJS-$(CONFIG_MMSH_PROTOCOL) += mmsh.o mms.o asf.o
 OBJS-$(CONFIG_MMST_PROTOCOL) += mmst.o mms.o asf.o
 OBJS-$(CONFIG_PIPE_PROTOCOL) += file.o
+OBJS-$(CONFIG_PROMPEG_PROTOCOL)  += prompeg.o
 OBJS-$(CONFIG_RTMP_PROTOCOL) += rtmpproto.o rtmppkt.o
 OBJS-$(CONFIG_RTMPE_PROTOCOL)+= rtmpproto.o rtmppkt.o
 OBJS-$(CONFIG_RTMPS_PROTOCOL)+= rtmpproto.o rtmppkt.o
diff --git a/libavformat/prompeg.c b/libavformat/prompeg.c
new file mode 100644
index 000..d4beb19
--- /dev/null
+++ b/libavformat/prompeg.c
@@ -0,0 +1,487 @@
+/*
+ * Pro-MPEG Code of Practice #3 Release 2 FEC
+ * Copyright (c) 2016 Mobibase, France (http://www.mobibase.com)
+ *
+ * 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
+ */
+
+/**
+ * @file
+ * Pro-MPEG Code of Practice #3 Release 2 FEC protocol
+ * @author Vlad Tarca 
+ */
+
+/*
+ * Reminder:
+
+ [RFC 2733] FEC Packet Structure
+
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   | RTP Header|
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   | 

Re: [FFmpeg-devel] [PATCH] avformat: Add Pro-MPEG CoP #3-R2 FEC protocol

2016-05-30 Thread Michael Niedermayer
On Mon, May 30, 2016 at 11:04:03AM +0200, Vlad Tarca wrote:
[...]
> +static int prompeg_init(URLContext *h, const uint8_t *buf, int size) {
> +PrompegContext *s = h->priv_data;
> +uint32_t seed;
> +int recovery_len, bitstring_len, rtp_buf_len;
> +int i;
> +
> +s->fec_buf = NULL;
> +s->rtp_buf = NULL;
> +
> +s->packet_idx = 0;
> +s->packet_idx_max = s->l * s->d;
> +s->packet_size = size;
> +

> +recovery_len = size - 12;

can size be INT_MIN ?
if so this can overflow and nothing after this line can correct this
the compiler has every right to crash you here or do anything else
signed overflow is undefined in C, unsigned is defined


> +if (recovery_len <= 0) {
> +av_log(h, AV_LOG_ERROR, "Invalid recovery length\n");
> +return AVERROR_INVALIDDATA;
> +}
> +s->recovery_len = recovery_len;
> +
> +rtp_buf_len = 12 + 16 + s->recovery_len;

same issue here


> +if (rtp_buf_len <= 0 || rtp_buf_len >= INT_MAX / sizeof (uint8_t)) {

sizeof (uint8_t) is 1

rtp_buf_len can never be larger than INT_MAX as its a int


[...]
> +static int prompeg_close(URLContext *h) {
> +PrompegContext *s = h->priv_data;
> +int i;
> +
> +ffurl_close(s->fec_col_hd);
> +ffurl_close(s->fec_row_hd);

ffurl_closep() also clears the pointer


[...]
> @@ -561,6 +616,9 @@ static int rtp_close(URLContext *h)
>  
>  ffurl_close(s->rtp_hd);
>  ffurl_close(s->rtcp_hd);

> +if (s->fec) {
> +ffurl_close(s->fec_hd);
> +}

why does this need a check ?
isnt fec_hd NULL if it shouldnt be closed ?

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

Old school: Use the lowest level language in which you can solve the problem
conveniently.
New school: Use the highest level language in which the latest supercomputer
can solve the problem without the user falling asleep waiting.


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


[FFmpeg-devel] [PATCH] avformat: Add Pro-MPEG CoP #3-R2 FEC protocol

2016-05-30 Thread Vlad Tarca
Hello,

> I think size needs to be checked to avoid integer overflow
> there is a check later but unless iam mising somthng thats too late

They were checked indirectly by av_malloc_array() and used only iff the init 
succeeded.
I added checks to avoid setting garbage in the context.

> this looks duplicated, can this be factored with the similar previous code ?

> sizeof(buf) or something, hardcoded 256 is bad, that can be missed
> if someone changes the array size

Some artefacts from rtpproto.c, someone might need to take a look at it at some 
point.
Fixed and used just prompeg_close() for cleanup.

Thanks


Signed-off-by: Vlad Tarca 
---
 Changelog   |   1 +
 doc/general.texi|   1 +
 doc/protocols.texi  |  35 
 libavformat/Makefile|   1 +
 libavformat/prompeg.c   | 491 
 libavformat/protocols.c |   1 +
 libavformat/rtpproto.c  |  64 ++-
 7 files changed, 591 insertions(+), 3 deletions(-)
 create mode 100644 libavformat/prompeg.c

diff --git a/Changelog b/Changelog
index 697b430..34bc23a 100644
--- a/Changelog
+++ b/Changelog
@@ -37,6 +37,7 @@ version :
 - Direct Stream Transfer (DST) decoder
 - loudnorm filter
 - MTAF demuxer and decoder
+- Pro-MPEG CoP #3-R2 FEC protocol
 
 version 3.0:
 - Common Encryption (CENC) MP4 encoding and decoding support
diff --git a/doc/general.texi b/doc/general.texi
index 2d3dd0b..80a434a 100644
--- a/doc/general.texi
+++ b/doc/general.texi
@@ -1126,6 +1126,7 @@ performance on systems without hardware floating point 
support).
 @item MMSH @tab X
 @item MMST @tab X
 @item pipe @tab X
+@item Pro-MPEG FEC @tab X
 @item RTMP @tab X
 @item RTMPE@tab X
 @item RTMPS@tab X
diff --git a/doc/protocols.texi b/doc/protocols.texi
index a9c9d0c..875fdac 100644
--- a/doc/protocols.texi
+++ b/doc/protocols.texi
@@ -513,6 +513,41 @@ time, which is valuable if data transmission is slow.
 Note that some formats (typically MOV), require the output protocol to
 be seekable, so they will fail with the pipe output protocol.
 
+@section prompeg
+
+Pro-MPEG Code of Practice #3 Release 2 FEC protocol.
+
+The Pro-MPEG CoP#3 FEC is a 2D parity-check forward error correction mechanism
+for MPEG-2 Transport Streams sent over RTP.
+
+This protocol must be used in conjunction with the @code{rtp_mpegts} muxer and
+the @code{rtp} protocol.
+
+The required syntax is:
+@example
+-f rtp_mpegts -fec prompeg=@var{option}=@var{val}... 
rtp://@var{hostname}:@var{port}
+@end example
+
+The destination UDP ports are @code{port + 2} for the column FEC stream
+and @code{port + 4} for the row FEC stream.
+
+This protocol accepts the following options:
+@table @option
+
+@item l=@var{n}
+The number of columns (4-20, LxD <= 100)
+
+@item d=@var{n}
+The number of rows (4-20, LxD <= 100)
+
+@end table
+
+Example usage:
+
+@example
+-f rtp_mpegts -fec prompeg=l=8:d=4 rtp://@var{hostname}:@var{port}
+@end example
+
 @section rtmp
 
 Real-Time Messaging Protocol.
diff --git a/libavformat/Makefile b/libavformat/Makefile
index 6684ead..90d7587 100644
--- a/libavformat/Makefile
+++ b/libavformat/Makefile
@@ -547,6 +547,7 @@ OBJS-$(CONFIG_MD5_PROTOCOL)  += md5proto.o
 OBJS-$(CONFIG_MMSH_PROTOCOL) += mmsh.o mms.o asf.o
 OBJS-$(CONFIG_MMST_PROTOCOL) += mmst.o mms.o asf.o
 OBJS-$(CONFIG_PIPE_PROTOCOL) += file.o
+OBJS-$(CONFIG_PROMPEG_PROTOCOL)  += prompeg.o
 OBJS-$(CONFIG_RTMP_PROTOCOL) += rtmpproto.o rtmppkt.o
 OBJS-$(CONFIG_RTMPE_PROTOCOL)+= rtmpproto.o rtmppkt.o
 OBJS-$(CONFIG_RTMPS_PROTOCOL)+= rtmpproto.o rtmppkt.o
diff --git a/libavformat/prompeg.c b/libavformat/prompeg.c
new file mode 100644
index 000..3e365c6
--- /dev/null
+++ b/libavformat/prompeg.c
@@ -0,0 +1,491 @@
+/*
+ * Pro-MPEG Code of Practice #3 Release 2 FEC
+ * Copyright (c) 2016 Mobibase, France (http://www.mobibase.com)
+ *
+ * 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
+ */
+
+/**
+ * @file
+ * Pro-MPEG Code of Practice #3 Release 2 FEC protocol
+ * @author Vlad Tarca 
+ */
+
+/*
+ * Reminder:
+
+ [RFC 2733] FEC Packet Structure
+
+   

Re: [FFmpeg-devel] [PATCH] avformat: Add Pro-MPEG CoP #3-R2 FEC protocol

2016-05-24 Thread Michael Niedermayer
On Wed, May 18, 2016 at 04:18:11PM +0200, Vlad Tarca wrote:
> >
> > Have you tested this on actual receivers?
> > Are you aware this won't work effectively because of the bursty nature of
> > FFmpeg?
> >
> > Kieran
> >
> 
> Hello,
> 
> I tested the FFmpeg version on a software receiver, not a hardware one. I
> initially implemented this for one of my applications based on VideoLAN's
> multicat and that version seemed to work well with hardware receivers.
> 
> Now that you mention it I can see there are discussions about the UDP burst
> issues. Do you know if there are any planned improvements?

there was a patch, ive applied and fixed the worst of it
you can now prevent bursts with -packet_gap

What is missing now is to add either some -bandwidth option or even
better make udp use the bitrate or PCR/SCR to time the outputted udp
packets. Which would be nicer than the packet_gap based system

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

Let us carefully observe those good qualities wherein our enemies excel us
and endeavor to excel them, by avoiding what is faulty, and imitating what
is excellent in them. -- Plutarch


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


Re: [FFmpeg-devel] [PATCH] avformat: Add Pro-MPEG CoP #3-R2 FEC protocol

2016-05-24 Thread Michael Niedermayer
On Wed, May 18, 2016 at 02:46:33PM +0200, Vlad Tarca wrote:
> Fixed a type issue in xor added after the last modification and cleaned up 
> unnecessary NULL checks for av_dict_free
[...]

> +static int prompeg_init(URLContext *h, const uint8_t *buf, int size) {
> +PrompegContext *s = h->priv_data;
> +uint32_t seed;
> +int bitstring_len, rtp_buf_len, i;
> +
> +s->packet_idx = 0;
> +s->packet_idx_max = s->l * s->d;
> +s->packet_size = size;
> +s->recovery_len = size - 12;

I think size needs to be checked to avoid integer overflow
there is a check later but unless iam mising somthng thats too late

> +bitstring_len = s->recovery_len + 8;
> +s->bitstring_size = bitstring_len * sizeof (uint8_t);
> +rtp_buf_len = 12 + 16 + s->recovery_len;

a check for size being too large is missing too i think


> +s->rtp_buf_size = rtp_buf_len * sizeof (uint8_t);
> +s->fec_buf_len = 1 + 2 * s->l; // row + column tmp + column out
> +
> +if (h->flags & AVFMT_FLAG_BITEXACT) {
> +s->rtp_col_sn = 0;
> +s->rtp_row_sn = 0;
> +} else {
> +seed = av_get_random_seed();
> +s->rtp_col_sn = seed & 0x0fff;
> +s->rtp_row_sn = (seed >> 16) & 0x0fff;
> +}
> +
> +s->rtp_buf = NULL;
> +s->fec_buf = av_malloc_array(s->fec_buf_len, sizeof (PrompegFec*));
> +if (!s->fec_buf) {
> +goto fail;
> +}
> +for (i = 0; i < s->fec_buf_len; i++) {
> +s->fec_buf[i] = av_malloc(sizeof (PrompegFec));
> +if (!s->fec_buf[i]) {
> +goto fail;
> +}
> +s->fec_buf[i]->bitstring = av_malloc_array(bitstring_len, sizeof 
> (uint8_t));
> +if (!s->fec_buf[i]->bitstring) {
> +av_freep(>fec_buf[i]);
> +goto fail;
> +}
> +}
> +s->fec_row = *s->fec_buf;
> +s->fec_col = s->fec_buf + 1;
> +s->fec_col_tmp = s->fec_buf + 1 + s->l;
> +
> +s->rtp_buf = av_malloc_array(rtp_buf_len, sizeof (uint8_t));
> +if (!s->rtp_buf) {
> +goto fail;
> +}
> +memset(s->rtp_buf, 0, s->rtp_buf_size);
> +
> +s->init = 0;
> +s->first = 1;
> +
> +return 0;
> +
> +fail:
> +if (s->fec_buf) {
> +for (i = 0; i < s->fec_buf_len; i++) {
> +if (!s->fec_buf[i]) {
> +break;
> +}
> +av_free(s->fec_buf[i]->bitstring);
> +av_freep(>fec_buf[i]);
> +}
> +av_freep(>fec_buf);
> +}

> +if (s->rtp_buf) {
> +av_freep(>rtp_buf);
> +}

redudant NULL check


[...]
> +static int prompeg_close(URLContext *h) {
> +PrompegContext *s = h->priv_data;
> +int i;
> +
> +ffurl_close(s->fec_col_hd);
> +ffurl_close(s->fec_row_hd);
> +
> +if (s->fec_buf) {
> +for (i = 0; i < s->fec_buf_len; i++) {
> +av_free(s->fec_buf[i]->bitstring);
> +av_freep(>fec_buf[i]);
> +}
> +av_freep(>fec_buf);
> +}
> +if (s->rtp_buf)
> +av_freep(>rtp_buf);

this looks duplicated, can this be factored with the similar previous
code ?


[...]
> @@ -377,6 +382,33 @@ static int rtp_open(URLContext *h, const char *uri, int 
> flags)
>  }
>  }
>  
> +if (s->fec_options_str) {
> +p = s->fec_options_str;
> +
> +if (!(fec_protocol = av_get_token(, "="))) {
> +av_log(h, AV_LOG_ERROR, "Failed to parse the FEC protocol 
> value\n");
> +goto fail;
> +}
> +if (strcmp(fec_protocol, "prompeg")) {
> +av_log(h, AV_LOG_ERROR, "Unsupported FEC protocol %s\n", 
> fec_protocol);
> +goto fail;
> +}
> +
> +p = s->fec_options_str + strlen(fec_protocol);
> +while (*p && *p == '=') p++;
> +
> +if (av_dict_parse_string(_opts, p, "=", ":", 0) < 0) {
> +av_log(h, AV_LOG_ERROR, "Failed to parse the FEC options\n");
> +goto fail;
> +}
> +if (s->ttl > 0) {

> +snprintf(buf, 256, "%d", s->ttl);

sizeif(buf) or something, hardcoded 256 is bad, that can be missed
if someone changes the array size

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

What does censorship reveal? It reveals fear. -- Julian Assange


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


Re: [FFmpeg-devel] [PATCH] avformat: Add Pro-MPEG CoP #3-R2 FEC protocol

2016-05-18 Thread Vlad Tarca
>
> Have you tested this on actual receivers?
> Are you aware this won't work effectively because of the bursty nature of
> FFmpeg?
>
> Kieran
>

Hello,

I tested the FFmpeg version on a software receiver, not a hardware one. I
initially implemented this for one of my applications based on VideoLAN's
multicat and that version seemed to work well with hardware receivers.

Now that you mention it I can see there are discussions about the UDP burst
issues. Do you know if there are any planned improvements?

Thanks,
Vlad T.
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


Re: [FFmpeg-devel] [PATCH] avformat: Add Pro-MPEG CoP #3-R2 FEC protocol

2016-05-18 Thread Kieran Kunhya
On Wed, 18 May 2016 at 13:52 Vlad Tarca  wrote:

> Fixed a type issue in xor added after the last modification and cleaned up
> unnecessary NULL checks for av_dict_free
>
>
Hi,

Have you tested this on actual receivers?
Are you aware this won't work effectively because of the bursty nature of
FFmpeg?

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


[FFmpeg-devel] [PATCH] avformat: Add Pro-MPEG CoP #3-R2 FEC protocol

2016-05-18 Thread Vlad Tarca
Fixed a type issue in xor added after the last modification and cleaned up 
unnecessary NULL checks for av_dict_free

Signed-off-by: Vlad Tarca 
---
 Changelog   |   1 +
 doc/general.texi|   1 +
 doc/protocols.texi  |  35 
 libavformat/Makefile|   1 +
 libavformat/prompeg.c   | 490 
 libavformat/protocols.c |   1 +
 libavformat/rtpproto.c  |  64 ++-
 7 files changed, 590 insertions(+), 3 deletions(-)
 create mode 100644 libavformat/prompeg.c

diff --git a/Changelog b/Changelog
index 402594d..15b3663 100644
--- a/Changelog
+++ b/Changelog
@@ -35,6 +35,7 @@ version :
 - Generic OpenMAX IL encoder with support for Raspberry Pi
 - IFF ANIM demuxer & decoder
 - Direct Stream Transfer (DST) decoder
+- Pro-MPEG CoP #3-R2 FEC protocol
 
 version 3.0:
 - Common Encryption (CENC) MP4 encoding and decoding support
diff --git a/doc/general.texi b/doc/general.texi
index 2d3dd0b..80a434a 100644
--- a/doc/general.texi
+++ b/doc/general.texi
@@ -1126,6 +1126,7 @@ performance on systems without hardware floating point 
support).
 @item MMSH @tab X
 @item MMST @tab X
 @item pipe @tab X
+@item Pro-MPEG FEC @tab X
 @item RTMP @tab X
 @item RTMPE@tab X
 @item RTMPS@tab X
diff --git a/doc/protocols.texi b/doc/protocols.texi
index a1084bd..fed0f3b 100644
--- a/doc/protocols.texi
+++ b/doc/protocols.texi
@@ -513,6 +513,41 @@ time, which is valuable if data transmission is slow.
 Note that some formats (typically MOV), require the output protocol to
 be seekable, so they will fail with the pipe output protocol.
 
+@section prompeg
+
+Pro-MPEG Code of Practice #3 Release 2 FEC protocol.
+
+The Pro-MPEG CoP#3 FEC is a 2D parity-check forward error correction mechanism
+for MPEG-2 Transport Streams sent over RTP.
+
+This protocol must be used in conjunction with the @code{rtp_mpegts} muxer and
+the @code{rtp} protocol.
+
+The required syntax is:
+@example
+-f rtp_mpegts -fec prompeg=@var{option}=@var{val}... 
rtp://@var{hostname}:@var{port}
+@end example
+
+The destination UDP ports are @code{port + 2} for the column FEC stream
+and @code{port + 4} for the row FEC stream.
+
+This protocol accepts the following options:
+@table @option
+
+@item l=@var{n}
+The number of columns (4-20, LxD <= 100)
+
+@item d=@var{n}
+The number of rows (4-20, LxD <= 100)
+
+@end table
+
+Example usage:
+
+@example
+-f rtp_mpegts -fec prompeg=l=8:d=4 rtp://@var{hostname}:@var{port}
+@end example
+
 @section rtmp
 
 Real-Time Messaging Protocol.
diff --git a/libavformat/Makefile b/libavformat/Makefile
index 742aff5..d29a9cc 100644
--- a/libavformat/Makefile
+++ b/libavformat/Makefile
@@ -546,6 +546,7 @@ OBJS-$(CONFIG_MD5_PROTOCOL)  += md5proto.o
 OBJS-$(CONFIG_MMSH_PROTOCOL) += mmsh.o mms.o asf.o
 OBJS-$(CONFIG_MMST_PROTOCOL) += mmst.o mms.o asf.o
 OBJS-$(CONFIG_PIPE_PROTOCOL) += file.o
+OBJS-$(CONFIG_PROMPEG_PROTOCOL)  += prompeg.o
 OBJS-$(CONFIG_RTMP_PROTOCOL) += rtmpproto.o rtmppkt.o
 OBJS-$(CONFIG_RTMPE_PROTOCOL)+= rtmpproto.o rtmppkt.o
 OBJS-$(CONFIG_RTMPS_PROTOCOL)+= rtmpproto.o rtmppkt.o
diff --git a/libavformat/prompeg.c b/libavformat/prompeg.c
new file mode 100644
index 000..eb87447
--- /dev/null
+++ b/libavformat/prompeg.c
@@ -0,0 +1,490 @@
+/*
+ * Pro-MPEG Code of Practice #3 Release 2 FEC
+ * Copyright (c) 2016 Mobibase, France (http://www.mobibase.com)
+ *
+ * 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
+ */
+
+/**
+ * @file
+ * Pro-MPEG Code of Practice #3 Release 2 FEC protocol
+ * @author Vlad Tarca 
+ */
+
+/*
+ * Reminder:
+
+ [RFC 2733] FEC Packet Structure
+
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   | RTP Header|
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   | FEC Header|
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   | FEC Payload   |
+   |   |
+   

[FFmpeg-devel] [PATCH] avformat: Add Pro-MPEG CoP #3-R2 FEC protocol

2016-05-16 Thread Vlad Tarca
Pro-MPEG Code of Practice #3 release 2 forward error correction for rtp_mpegts 
streams

Signed-off-by: Vlad Tarca 
---
 Changelog   |   1 +
 doc/general.texi|   1 +
 doc/protocols.texi  |  35 
 libavformat/Makefile|   1 +
 libavformat/prompeg.c   | 489 
 libavformat/protocols.c |   1 +
 libavformat/rtpproto.c  |  64 ++-
 7 files changed, 589 insertions(+), 3 deletions(-)
 create mode 100644 libavformat/prompeg.c

diff --git a/Changelog b/Changelog
index 402594d..15b3663 100644
--- a/Changelog
+++ b/Changelog
@@ -35,6 +35,7 @@ version :
 - Generic OpenMAX IL encoder with support for Raspberry Pi
 - IFF ANIM demuxer & decoder
 - Direct Stream Transfer (DST) decoder
+- Pro-MPEG CoP #3-R2 FEC protocol
 
 version 3.0:
 - Common Encryption (CENC) MP4 encoding and decoding support
diff --git a/doc/general.texi b/doc/general.texi
index 2d3dd0b..80a434a 100644
--- a/doc/general.texi
+++ b/doc/general.texi
@@ -1126,6 +1126,7 @@ performance on systems without hardware floating point 
support).
 @item MMSH @tab X
 @item MMST @tab X
 @item pipe @tab X
+@item Pro-MPEG FEC @tab X
 @item RTMP @tab X
 @item RTMPE@tab X
 @item RTMPS@tab X
diff --git a/doc/protocols.texi b/doc/protocols.texi
index a1084bd..fed0f3b 100644
--- a/doc/protocols.texi
+++ b/doc/protocols.texi
@@ -513,6 +513,41 @@ time, which is valuable if data transmission is slow.
 Note that some formats (typically MOV), require the output protocol to
 be seekable, so they will fail with the pipe output protocol.
 
+@section prompeg
+
+Pro-MPEG Code of Practice #3 Release 2 FEC protocol.
+
+The Pro-MPEG CoP#3 FEC is a 2D parity-check forward error correction mechanism
+for MPEG-2 Transport Streams sent over RTP.
+
+This protocol must be used in conjunction with the @code{rtp_mpegts} muxer and
+the @code{rtp} protocol.
+
+The required syntax is:
+@example
+-f rtp_mpegts -fec prompeg=@var{option}=@var{val}... 
rtp://@var{hostname}:@var{port}
+@end example
+
+The destination UDP ports are @code{port + 2} for the column FEC stream
+and @code{port + 4} for the row FEC stream.
+
+This protocol accepts the following options:
+@table @option
+
+@item l=@var{n}
+The number of columns (4-20, LxD <= 100)
+
+@item d=@var{n}
+The number of rows (4-20, LxD <= 100)
+
+@end table
+
+Example usage:
+
+@example
+-f rtp_mpegts -fec prompeg=l=8:d=4 rtp://@var{hostname}:@var{port}
+@end example
+
 @section rtmp
 
 Real-Time Messaging Protocol.
diff --git a/libavformat/Makefile b/libavformat/Makefile
index 742aff5..d29a9cc 100644
--- a/libavformat/Makefile
+++ b/libavformat/Makefile
@@ -546,6 +546,7 @@ OBJS-$(CONFIG_MD5_PROTOCOL)  += md5proto.o
 OBJS-$(CONFIG_MMSH_PROTOCOL) += mmsh.o mms.o asf.o
 OBJS-$(CONFIG_MMST_PROTOCOL) += mmst.o mms.o asf.o
 OBJS-$(CONFIG_PIPE_PROTOCOL) += file.o
+OBJS-$(CONFIG_PROMPEG_PROTOCOL)  += prompeg.o
 OBJS-$(CONFIG_RTMP_PROTOCOL) += rtmpproto.o rtmppkt.o
 OBJS-$(CONFIG_RTMPE_PROTOCOL)+= rtmpproto.o rtmppkt.o
 OBJS-$(CONFIG_RTMPS_PROTOCOL)+= rtmpproto.o rtmppkt.o
diff --git a/libavformat/prompeg.c b/libavformat/prompeg.c
new file mode 100644
index 000..d60e40b
--- /dev/null
+++ b/libavformat/prompeg.c
@@ -0,0 +1,489 @@
+/*
+ * Pro-MPEG Code of Practice #3 Release 2 FEC
+ * Copyright (c) 2016 Mobibase, France (http://www.mobibase.com)
+ *
+ * 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
+ */
+
+/**
+ * @file
+ * Pro-MPEG Code of Practice #3 Release 2 FEC protocol
+ * @author Vlad Tarca 
+ */
+
+/*
+ * Reminder:
+
+ [RFC 2733] FEC Packet Structure
+
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   | RTP Header|
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   | FEC Header|
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   | FEC Payload   |
+   |   |
+   

Re: [FFmpeg-devel] [PATCH] avformat: Add Pro-MPEG CoP #3-R2 FEC protocol

2016-05-14 Thread Michael Niedermayer
Hi

On Fri, May 13, 2016 at 04:30:34PM +0200, Vlad Tarca wrote:
> Pro-MPEG Code of Practice #3 release 2 forward error correction for 
> rtp_mpegts streams
> 
[...]
> +static const AVClass prompeg_class = {
> +.class_name = "prompeg",
> +.item_name  = av_default_item_name,
> +.option = options,
> +.version= LIBAVUTIL_VERSION_INT,
> +};
> +
> +static void xor64(const uint8_t *in1, const uint8_t *in2, uint8_t *out, int 
> size) {
> +const uint64_t *p1, *p2;
> +const uint8_t *q1, *q2;
> +uint64_t *px;
> +uint8_t *qx;
> +int i, n, s;
> +
> +n = size / sizeof (uint64_t);
> +s = n * sizeof (uint64_t);
> +
> +p1 = (uint64_t*) in1;
> +p2 = (uint64_t*) in2;
> +px = (uint64_t*) out;




> +
> +for (i = 0; i < n; i++) {
> +px[i] = p1[i] ^ p2[i];

this is a strict aliassing violation probably or at least it can
become one easily if any access to this array is different than
char* type
its ore robust to use union or AV_RN64A/AV_WN64A or similar


> +}
> +
> +if (s == size)
> +return;
> +
> +q1 = in1 + s;
> +q2 = in2 + s;
> +qx = out + s;
> +n = size - s;
> +
> +for (i = 0; i < n; i++) {
> +qx[i] = q1[i] ^ q2[i];
> +}
> +}
> +

> +static inline uint32_t rtp_get_ts(const uint8_t *buf) {
> +return (buf[4] << 24) | (buf[5] << 16) | (buf[6] << 8) | buf[7];

AV_RB32()


> +}
> +

> +static inline uint16_t rtp_get_sn(const uint8_t *buf) {
> +return (buf[2] << 8) | buf[3];

AV_RB16()

[...]

> +static int prompeg_init(URLContext *h, const uint8_t *buf, int size) {
> +PrompegContext *s = h->priv_data;
> +int i;
> +
> +s->packet_idx = 0;
> +s->packet_idx_max = s->l * s->d;
> +s->packet_size = size;
> +s->length_recovery = size - 12;
> +s->bitstring_size = (s->length_recovery + 8) * sizeof (uint8_t);
> +s->fec_buf_len = 1 + 2 * s->l; // row + column tmp + column out
> +s->rtp_buf_size = (12 + 16 + s->length_recovery) * sizeof (uint8_t);
> +s->fec_buf = NULL;
> +s->rtp_buf = NULL;

> +s->rtp_col_sn = av_get_random_seed() & 0x0fff;
> +s->rtp_row_sn = av_get_random_seed() & 0x0fff;

you need only one call, it contains enough bits
av_get_random_seed() is slow
also a bitexact mode as in AVFMT_FLAG_BITEXACT might be usefull


> +
> +s->fec_buf = av_malloc(s->fec_buf_len * sizeof (PrompegFec*));

av_malloc_array()


> +if (!s->fec_buf) {
> +goto fail;
> +}
> +for (i = 0; i < s->fec_buf_len; i++) {
> +s->fec_buf[i] = av_malloc(sizeof (PrompegFec));
> +if (!s->fec_buf[i]) {
> +goto fail;
> +}
> +s->fec_buf[i]->bitstring = av_malloc(s->bitstring_size);
> +if (!s->fec_buf[i]->bitstring) {

> +av_free(s->fec_buf[i]);
> +s->fec_buf[i] = NULL;

av_freep()


[...]

> +static int prompeg_write(URLContext *h, const uint8_t *buf, int size) {
> +PrompegContext *s = h->priv_data;
> +PrompegFec *fec_tmp;
> +uint8_t *bitstring = NULL;
> +int col_idx, col_out_idx, row_idx;
> +int ret;
> +
> +if (s->init && ((ret = prompeg_init(h, buf, size)) < 0))
> +goto fail;
> +
> +if ((ret = prompeg_create_bitstring(h, buf, size, )) < 0)
> +goto fail;
> +
> +col_idx = s->packet_idx % s->l;
> +row_idx = s->packet_idx / s->l % s->d;
> +
> +// FEC' (row) send block-aligned, xor
> +if (col_idx == 0) {
> +if (!s->first || s->packet_idx > 0) {
> +if ((ret = prompeg_write_fec(h, s->fec_row, PROMPEG_FEC_ROW)) < 
> 0)
> +goto fail;
> +}
> +memcpy(s->fec_row->bitstring, bitstring, s->bitstring_size);
> +s->fec_row->sn = rtp_get_sn(buf);
> +s->fec_row->ts = rtp_get_ts(buf);
> +} else {
> +xor64(s->fec_row->bitstring, bitstring, s->fec_row->bitstring,
> +s->bitstring_size);
> +}
> +
> +// FEC (column) xor
> +if (row_idx == 0) {
> +if (!s->first) {
> +// swap fec_col and fec_col_tmp
> +fec_tmp = s->fec_col[col_idx];
> +s->fec_col[col_idx] = s->fec_col_tmp[col_idx];
> +s->fec_col_tmp[col_idx] = fec_tmp;
> +}
> +memcpy(s->fec_col_tmp[col_idx]->bitstring, bitstring, 
> s->bitstring_size);
> +s->fec_col_tmp[col_idx]->sn = rtp_get_sn(buf);
> +s->fec_col_tmp[col_idx]->ts = rtp_get_ts(buf);
> +} else {
> +xor64(s->fec_col_tmp[col_idx]->bitstring, bitstring,
> +s->fec_col_tmp[col_idx]->bitstring, s->bitstring_size);
> +}
> +
> +// FEC (column) send block-aligned
> +if (!s->first && s->packet_idx % s->d == 0) {
> +col_out_idx = s->packet_idx / s->l;
> +if ((ret = prompeg_write_fec(h, s->fec_col[col_out_idx], 
> PROMPEG_FEC_COL)) < 0)
> +goto fail;
> +}
> +
> +if (++s->packet_idx >= s->packet_idx_max) {
> +s->packet_idx = 0;
> +if (s->first)
> +s->first = 

[FFmpeg-devel] [PATCH] avformat: Add Pro-MPEG CoP #3-R2 FEC protocol

2016-05-13 Thread Vlad Tarca
Pro-MPEG Code of Practice #3 release 2 forward error correction for rtp_mpegts 
streams

Signed-off-by: Vlad Tarca 
---
 Changelog   |   1 +
 doc/general.texi|   1 +
 doc/protocols.texi  |  38 
 libavformat/Makefile|   1 +
 libavformat/prompeg.c   | 493 
 libavformat/protocols.c |   1 +
 libavformat/rtpproto.c  |  62 +-
 7 files changed, 595 insertions(+), 2 deletions(-)
 create mode 100644 libavformat/prompeg.c

diff --git a/Changelog b/Changelog
index 3f343ce..d6a882f 100644
--- a/Changelog
+++ b/Changelog
@@ -34,6 +34,7 @@ version :
 - DTS Express (LBR) decoder
 - Generic OpenMAX IL encoder with support for Raspberry Pi
 - IFF ANIM demuxer & decoder
+- Pro-MPEG CoP #3-R2 FEC protocol
 
 version 3.0:
 - Common Encryption (CENC) MP4 encoding and decoding support
diff --git a/doc/general.texi b/doc/general.texi
index 59ea4f4..2cbf41c 100644
--- a/doc/general.texi
+++ b/doc/general.texi
@@ -1124,6 +1124,7 @@ performance on systems without hardware floating point 
support).
 @item MMSH @tab X
 @item MMST @tab X
 @item pipe @tab X
+@item Pro-MPEG FEC @tab X
 @item RTMP @tab X
 @item RTMPE@tab X
 @item RTMPS@tab X
diff --git a/doc/protocols.texi b/doc/protocols.texi
index a1084bd..7c19dd8 100644
--- a/doc/protocols.texi
+++ b/doc/protocols.texi
@@ -513,6 +513,44 @@ time, which is valuable if data transmission is slow.
 Note that some formats (typically MOV), require the output protocol to
 be seekable, so they will fail with the pipe output protocol.
 
+@section prompeg
+
+Pro-MPEG Code of Practice #3 Release 2 FEC protocol.
+
+The Pro-MPEG CoP#3 FEC is a 2D parity-check forward error correction mechanism
+for MPEG-2 Transport Streams sent over RTP.
+
+This protocol must be used in conjunction with the @code{rtp_mpegts} muxer and
+the @code{rtp} protocol.
+
+The required syntax is:
+@example
+-f rtp_mpegts -fec prompeg=@var{option}=@var{val}... 
rtp://@var{hostname}:@var{port}
+@end example
+
+The destination UDP ports are @code{port + 2} for the column FEC stream
+and @code{port + 4} for the row FEC stream.
+
+This protocol accepts the following options:
+@table @option
+
+@item l=@var{n}
+The number of columns (4-20, LxD <= 100)
+
+@item d=@var{n}
+The number of rows (4-20, LxD <= 100)
+
+@item ttl=@var{n}
+Set the TTL (Time-To-Live) value (for multicast only).
+
+@end table
+
+Example usage:
+
+@example
+-f rtp_mpegts -fec prompeg=l=8:d=4 rtp://@var{hostname}:@var{port}
+@end example
+
 @section rtmp
 
 Real-Time Messaging Protocol.
diff --git a/libavformat/Makefile b/libavformat/Makefile
index abfbc37..b1d6798 100644
--- a/libavformat/Makefile
+++ b/libavformat/Makefile
@@ -546,6 +546,7 @@ OBJS-$(CONFIG_MD5_PROTOCOL)  += md5proto.o
 OBJS-$(CONFIG_MMSH_PROTOCOL) += mmsh.o mms.o asf.o
 OBJS-$(CONFIG_MMST_PROTOCOL) += mmst.o mms.o asf.o
 OBJS-$(CONFIG_PIPE_PROTOCOL) += file.o
+OBJS-$(CONFIG_PROMPEG_PROTOCOL)  += prompeg.o
 OBJS-$(CONFIG_RTMP_PROTOCOL) += rtmpproto.o rtmppkt.o
 OBJS-$(CONFIG_RTMPE_PROTOCOL)+= rtmpproto.o rtmppkt.o
 OBJS-$(CONFIG_RTMPS_PROTOCOL)+= rtmpproto.o rtmppkt.o
diff --git a/libavformat/prompeg.c b/libavformat/prompeg.c
new file mode 100644
index 000..08409d8
--- /dev/null
+++ b/libavformat/prompeg.c
@@ -0,0 +1,493 @@
+/*
+ * Pro-MPEG Code of Practice #3 Release 2 FEC
+ * Copyright (c) 2016 Mobibase, France (http://www.mobibase.com)
+ *
+ * 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
+ */
+
+/**
+ * @file
+ * Pro-MPEG Code of Practice #3 Release 2 FEC protocol
+ * @author Vlad Tarca 
+ */
+
+/*
+ * Reminder:
+
+ [RFC 2733] FEC Packet Structure
+
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   | RTP Header|
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   | FEC Header|
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   | FEC Payload   |
+   |