[libav-devel] [PATCH] rtmp: Support AMF_DATA_TYPE_MIXEDARRAY

2013-09-21 Thread Luca Barbato
And fix the AMF_DATA_TYPE_ARRAY parsing while at it.

A MIXEDARRAY type, as the ARRAY, store the number of elements in
an uint32 before the list. The ARRAY is strict and does not have
an OBJECT terminator, MIXEDARRAY behaves like an OBJECT type and
a different than stated number of element can be present.
---

A bit more complete.

 libavformat/rtmppkt.c | 25 -
 1 file changed, 16 insertions(+), 9 deletions(-)

diff --git a/libavformat/rtmppkt.c b/libavformat/rtmppkt.c
index 922ca3e..ca1ef75 100644
--- a/libavformat/rtmppkt.c
+++ b/libavformat/rtmppkt.c
@@ -370,19 +370,22 @@ void ff_rtmp_packet_destroy(RTMPPacket *pkt)
 int ff_amf_tag_size(const uint8_t *data, const uint8_t *data_end)
 {
 const uint8_t *base = data;
+unsigned nb = -1;
+AMFDataType type;

 if (data = data_end)
 return -1;
-switch (*data++) {
+switch ((type = *data++)) {
 case AMF_DATA_TYPE_NUMBER:  return 9;
 case AMF_DATA_TYPE_BOOL:return 2;
 case AMF_DATA_TYPE_STRING:  return 3 + AV_RB16(data);
 case AMF_DATA_TYPE_LONG_STRING: return 5 + AV_RB32(data);
 case AMF_DATA_TYPE_NULL:return 1;
+case AMF_DATA_TYPE_MIXEDARRAY:
 case AMF_DATA_TYPE_ARRAY:
-data += 4;
+nb = bytestream_get_be32(data);
 case AMF_DATA_TYPE_OBJECT:
-for (;;) {
+while (nb--  0 || type != AMF_DATA_TYPE_ARRAY) {
 int size = bytestream_get_be16(data);
 int t;
 if (!size) {
@@ -474,12 +477,13 @@ static const char* rtmp_packet_type(int type)
 static void amf_tag_contents(void *ctx, const uint8_t *data,
  const uint8_t *data_end)
 {
-unsigned int size;
+unsigned int size, nb = -1;
 char buf[1024];
+AMFDataType type;

 if (data = data_end)
 return;
-switch (*data++) {
+switch ((type = *data++)) {
 case AMF_DATA_TYPE_NUMBER:
 av_log(ctx, AV_LOG_DEBUG,  number %g\n, 
av_int2double(AV_RB64(data)));
 return;
@@ -488,7 +492,7 @@ static void amf_tag_contents(void *ctx, const uint8_t *data,
 return;
 case AMF_DATA_TYPE_STRING:
 case AMF_DATA_TYPE_LONG_STRING:
-if (data[-1] == AMF_DATA_TYPE_STRING) {
+if (type == AMF_DATA_TYPE_STRING) {
 size = bytestream_get_be16(data);
 } else {
 size = bytestream_get_be32(data);
@@ -501,19 +505,22 @@ static void amf_tag_contents(void *ctx, const uint8_t 
*data,
 case AMF_DATA_TYPE_NULL:
 av_log(ctx, AV_LOG_DEBUG,  NULL\n);
 return;
+case AMF_DATA_TYPE_MIXEDARRAY:
 case AMF_DATA_TYPE_ARRAY:
-data += 4;
+nb = bytestream_get_be32(data);
 case AMF_DATA_TYPE_OBJECT:
 av_log(ctx, AV_LOG_DEBUG,  {\n);
-for (;;) {
+while (nb--  0 || type != AMF_DATA_TYPE_ARRAY) {
 int t;
 size = bytestream_get_be16(data);
-av_strlcpy(buf, data, FFMIN(sizeof(buf), size + 1));
+size = FFMIN(size, sizeof(buf) - 1);
 if (!size) {
 av_log(ctx, AV_LOG_DEBUG,  }\n);
 data++;
 break;
 }
+memcpy(buf, data, size);
+buf[size] = 0;
 if (size = data_end - data)
 return;
 data += size;
--
1.8.3.2

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


[libav-devel] [PATCH 1/2] rtmp: Refactor get_packet

2013-09-21 Thread Luca Barbato
---
 libavformat/rtmpproto.c | 119 +++-
 1 file changed, 57 insertions(+), 62 deletions(-)

diff --git a/libavformat/rtmpproto.c b/libavformat/rtmpproto.c
index a2dffd0..2b2baa3 100644
--- a/libavformat/rtmpproto.c
+++ b/libavformat/rtmpproto.c
@@ -2061,65 +2061,81 @@ static int handle_invoke(URLContext *s, RTMPPacket *pkt)
 return ret;
 }
 
-static int handle_notify(URLContext *s, RTMPPacket *pkt) {
-RTMPContext *rt  = s-priv_data;
-const uint8_t *p = NULL;
-uint8_t commandbuffer[64];
-char statusmsg[128];
-int stringlen;
-GetByteContext gbc;
-PutByteContext pbc;
-uint32_t ts;
-int old_flv_size, err;
-const uint8_t *datatowrite;
-unsigned datatowritelength;
-
-p = pkt-data;
-bytestream2_init(gbc, p, pkt-size);
-if (ff_amf_read_string(gbc, commandbuffer, sizeof(commandbuffer),
-   stringlen))
-return AVERROR_INVALIDDATA;
-if (!strcmp(commandbuffer, @setDataFrame)) {
-datatowrite   = gbc.buffer;
-datatowritelength = bytestream2_get_bytes_left(gbc);
-if (ff_amf_read_string(gbc, statusmsg,
-   sizeof(statusmsg), stringlen))
-return AVERROR_INVALIDDATA;
-} else {
-datatowrite   = pkt-data;
-datatowritelength = pkt-size;
-}
-
-/* Provide ECMAArray to flv */
-ts = pkt-timestamp;
+static int update_offset(RTMPContext *rt, int size)
+{
+int old_flv_size;
 
 // generate packet header and put data into buffer for FLV demuxer
 if (rt-flv_off  rt-flv_size) {
 // There is old unread data in the buffer, thus append at the end
 old_flv_size  = rt-flv_size;
-rt-flv_size += datatowritelength + 15;
+rt-flv_size += size + 15;
 } else {
 // All data has been read, write the new data at the start of the 
buffer
 old_flv_size = 0;
-rt-flv_size = datatowritelength + 15;
+rt-flv_size = size + 15;
 rt-flv_off  = 0;
 }
 
-if ((err = av_reallocp(rt-flv_data, rt-flv_size))  0)
-return err;
+return old_flv_size;
+}
+
+static int append_flv_data(RTMPContext *rt, RTMPPacket *pkt, int skip)
+{
+int old_flv_size, ret;
+PutByteContext pbc;
+const uint8_t *data = pkt-data + skip;
+const int size  = pkt-size - skip;
+uint32_t ts = pkt-timestamp;
+
+av_log(NULL, AV_LOG_ERROR, Timestamp %d\n,
+   ts);
+
+old_flv_size = update_offset(rt, size);
+
+if ((ret = av_reallocp(rt-flv_data, rt-flv_size))  0)
+return ret;
 bytestream2_init_writer(pbc, rt-flv_data, rt-flv_size);
 bytestream2_skip_p(pbc, old_flv_size);
 bytestream2_put_byte(pbc, pkt-type);
-bytestream2_put_be24(pbc, datatowritelength);
+bytestream2_put_be24(pbc, size);
 bytestream2_put_be24(pbc, ts);
 bytestream2_put_byte(pbc, ts  24);
 bytestream2_put_be24(pbc, 0);
-bytestream2_put_buffer(pbc, datatowrite, datatowritelength);
+bytestream2_put_buffer(pbc, data, size);
 bytestream2_put_be32(pbc, 0);
 
 return 0;
 }
 
+static int handle_notify(URLContext *s, RTMPPacket *pkt)
+{
+RTMPContext *rt  = s-priv_data;
+uint8_t commandbuffer[64];
+char statusmsg[128];
+int stringlen, ret, skip = 0;
+GetByteContext gbc;
+
+bytestream2_init(gbc, pkt-data, pkt-size);
+if (ff_amf_read_string(gbc, commandbuffer, sizeof(commandbuffer),
+   stringlen))
+return AVERROR_INVALIDDATA;
+
+av_log(NULL, AV_LOG_ERROR, RTMP %s\n, commandbuffer);
+
+// Skip the @setDataFrame string and validate it is a notification
+if (!strcmp(commandbuffer, @setDataFrame)) {
+skip = gbc.buffer - pkt-data;
+ret = ff_amf_read_string(gbc, statusmsg,
+ sizeof(statusmsg), stringlen);
+if (ret  0)
+return AVERROR_INVALIDDATA;
+av_log(NULL, AV_LOG_ERROR, - %s\n, statusmsg);
+}
+
+return append_flv_data(rt, pkt, skip);
+}
+
 /**
  * Parse received packet and possibly perform some action depending on
  * the packet contents.
@@ -2247,35 +2263,14 @@ static int get_packet(URLContext *s, int for_header)
 ff_rtmp_packet_destroy(rpkt);
 continue;
 }
-if (rpkt.type == RTMP_PT_VIDEO || rpkt.type == RTMP_PT_AUDIO ||
-   (rpkt.type == RTMP_PT_NOTIFY 
-ff_amf_match_string(rpkt.data, rpkt.size, onMetaData))) {
-int err;
-ts = rpkt.timestamp;
-
-// generate packet header and put data into buffer for FLV demuxer
-rt-flv_off  = 0;
-rt-flv_size = rpkt.size + 15;
-if ((err = av_reallocp(rt-flv_data, rt-flv_size))  0)
-return err;
-p = rt-flv_data;
-bytestream_put_byte(p, rpkt.type);
-bytestream_put_be24(p, rpkt.size);
-bytestream_put_be24(p, ts);
-   

[libav-devel] [PATCH 2/2] rtmp: Refactor get_packet (part 2)

2013-09-21 Thread Luca Barbato
---
 libavformat/rtmpproto.c | 69 +
 1 file changed, 41 insertions(+), 28 deletions(-)

diff --git a/libavformat/rtmpproto.c b/libavformat/rtmpproto.c
index 2b2baa3..da84254 100644
--- a/libavformat/rtmpproto.c
+++ b/libavformat/rtmpproto.c
@@ -2187,6 +2187,46 @@ static int rtmp_parse_result(URLContext *s, RTMPContext 
*rt, RTMPPacket *pkt)
 return 0;
 }
 
+static int handle_metadata(RTMPContext *rt, RTMPPacket *pkt)
+{
+int ret, old_flv_size;
+const uint8_t *next;
+uint8_t *p;
+uint32_t size;
+uint32_t ts, cts, pts = 0;
+
+old_flv_size = update_offset(rt, pkt-size);
+
+if ((ret = av_reallocp(rt-flv_data, rt-flv_size))  0)
+return ret;
+
+next = pkt-data;
+p= rt-flv_data + old_flv_size;
+
+/* rewrite timestamps */
+ts = pkt-timestamp;
+while (next - pkt-data  pkt-size - 11) {
+*p++ = *next++;
+size = bytestream_get_be24(next);
+bytestream_put_be24(p, size);
+cts = bytestream_get_be24(next);
+cts |= bytestream_get_byte(next)  24;
+if (!pts)
+pts = cts;
+ts += cts - pts;
+pts = cts;
+bytestream_put_be24(p, ts);
+bytestream_put_byte(p, ts  24);
+memcpy(p, next, size + 3 + 4);
+next += size + 3 + 4;
+p+= size + 3 + 4;
+}
+memcpy(p, next, 11);
+
+return 0;
+}
+
+
 /**
  * Interact with the server by receiving and sending RTMP packets until
  * there is some significant data (media data or expected status notification).
@@ -2202,10 +2242,6 @@ static int get_packet(URLContext *s, int for_header)
 {
 RTMPContext *rt = s-priv_data;
 int ret;
-uint8_t *p;
-const uint8_t *next;
-uint32_t size;
-uint32_t ts, cts, pts=0;
 
 if (rt-state == STATE_STOPPED)
 return AVERROR_EOF;
@@ -2272,30 +2308,7 @@ static int get_packet(URLContext *s, int for_header)
 ff_rtmp_packet_destroy(rpkt);
 return ret;
 } else if (rpkt.type == RTMP_PT_METADATA) {
-int err;
-// we got raw FLV data, make it available for FLV demuxer
-rt-flv_off  = 0;
-rt-flv_size = rpkt.size;
-if ((err = av_reallocp(rt-flv_data, rt-flv_size))  0)
-return err;
-/* rewrite timestamps */
-next = rpkt.data;
-ts = rpkt.timestamp;
-while (next - rpkt.data  rpkt.size - 11) {
-next++;
-size = bytestream_get_be24(next);
-p=next;
-cts = bytestream_get_be24(next);
-cts |= bytestream_get_byte(next)  24;
-if (pts==0)
-pts=cts;
-ts += cts - pts;
-pts = cts;
-bytestream_put_be24(p, ts);
-bytestream_put_byte(p, ts  24);
-next += size + 3 + 4;
-}
-memcpy(rt-flv_data, rpkt.data, rpkt.size);
+ret = handle_metadata(rt, rpkt);
 ff_rtmp_packet_destroy(rpkt);
 return 0;
 }
-- 
1.8.3.2

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


[libav-devel] Refactor rtmp get_packet

2013-09-21 Thread Luca Barbato
Split in two to ease review. The second patch is just compile tested.

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


Re: [libav-devel] [PATCH] rtmp: Support AMF_DATA_TYPE_MIXEDARRAY

2013-09-21 Thread Martin Storsjö

On Sat, 21 Sep 2013, Luca Barbato wrote:


And fix the AMF_DATA_TYPE_ARRAY parsing while at it.

A MIXEDARRAY type, as the ARRAY, store the number of elements in
an uint32 before the list. The ARRAY is strict and does not have
an OBJECT terminator, MIXEDARRAY behaves like an OBJECT type and
a different than stated number of element can be present.
---

A bit more complete.

libavformat/rtmppkt.c | 25 -
1 file changed, 16 insertions(+), 9 deletions(-)

diff --git a/libavformat/rtmppkt.c b/libavformat/rtmppkt.c
index 922ca3e..ca1ef75 100644
--- a/libavformat/rtmppkt.c
+++ b/libavformat/rtmppkt.c
@@ -370,19 +370,22 @@ void ff_rtmp_packet_destroy(RTMPPacket *pkt)
int ff_amf_tag_size(const uint8_t *data, const uint8_t *data_end)
{
const uint8_t *base = data;
+unsigned nb = -1;
+AMFDataType type;

if (data = data_end)
return -1;
-switch (*data++) {
+switch ((type = *data++)) {
case AMF_DATA_TYPE_NUMBER:  return 9;
case AMF_DATA_TYPE_BOOL:return 2;
case AMF_DATA_TYPE_STRING:  return 3 + AV_RB16(data);
case AMF_DATA_TYPE_LONG_STRING: return 5 + AV_RB32(data);
case AMF_DATA_TYPE_NULL:return 1;
+case AMF_DATA_TYPE_MIXEDARRAY:
case AMF_DATA_TYPE_ARRAY:
-data += 4;
+nb = bytestream_get_be32(data);
case AMF_DATA_TYPE_OBJECT:
-for (;;) {
+while (nb--  0 || type != AMF_DATA_TYPE_ARRAY) {
int size = bytestream_get_be16(data);


I'm still not sure this is totally right for AMF_DATA_TYPE_ARRAY - this is 
used for parsing (or skipping past) the string names for each of the 
elements in an OBJECT or a MIXEDARRAY, but an ARRAY doesn't have string 
names for each of the elements at all.


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


[libav-devel] [PATCH] flv: Make onTextData parsing robust

2013-09-21 Thread Luca Barbato
Certain streaming servers do not preserve the order of the fields.
---

Updated to return an error if it can't skip.

 libavformat/flvdec.c | 86 
 1 file changed, 67 insertions(+), 19 deletions(-)

diff --git a/libavformat/flvdec.c b/libavformat/flvdec.c
index b8feeaf..dfd338d 100644
--- a/libavformat/flvdec.c
+++ b/libavformat/flvdec.c
@@ -634,35 +634,82 @@ static void clear_index_entries(AVFormatContext *s, 
int64_t pos)
 }
 }

+static int amf_skip_tag(AVIOContext *pb, AMFDataType type)
+{
+int nb = -1, ret;
+
+switch (type) {
+case AMF_DATA_TYPE_NUMBER:
+avio_skip(pb, 8);
+break;
+case AMF_DATA_TYPE_BOOL:
+avio_skip(pb, 1);
+break;
+case AMF_DATA_TYPE_STRING:
+avio_skip(pb, avio_rb16(pb));
+break;
+case AMF_DATA_TYPE_MIXEDARRAY:
+case AMF_DATA_TYPE_ARRAY:
+avio_skip(pb, 4);
+case AMF_DATA_TYPE_OBJECT:
+while(!pb-eof_reached 
+  (nb  0 || type != AMF_DATA_TYPE_ARRAY)) {
+int size = avio_rb16(pb);
+if (!size) {
+avio_skip(pb, 1);
+break;
+}
+avio_skip(pb, size);
+if ((ret = amf_skip_tag(pb, avio_r8(pb)))  0)
+return ret;
+}
+break;
+case AMF_DATA_TYPE_NULL:
+case AMF_DATA_TYPE_OBJECT_END:
+break;
+default:
+return AVERROR_INVALIDDATA;
+}
+return 0;
+}
+
 static int flv_data_packet(AVFormatContext *s, AVPacket *pkt,
int64_t dts, int64_t next)
 {
 AVIOContext *pb = s-pb;
 AVStream *st= NULL;
-AMFDataType type;
 char buf[20];
-int ret, i, length;
+int ret = AVERROR_INVALIDDATA;
+int i, length = -1;

-type = avio_r8(pb);
-if (type == AMF_DATA_TYPE_MIXEDARRAY)
+switch (avio_r8(pb)) {
+case AMF_DATA_TYPE_MIXEDARRAY:
 avio_seek(pb, 4, SEEK_CUR);
-else if (type != AMF_DATA_TYPE_OBJECT)
-return AVERROR_INVALIDDATA;
-
-amf_get_string(pb, buf, sizeof(buf));
-if (strcmp(buf, type) || avio_r8(pb) != AMF_DATA_TYPE_STRING)
-return AVERROR_INVALIDDATA;
+case AMF_DATA_TYPE_OBJECT:
+break;
+default:
+goto skip;
+}

-amf_get_string(pb, buf, sizeof(buf));
-// FIXME parse it as codec_id
-amf_get_string(pb, buf, sizeof(buf));
-if (strcmp(buf, text) || avio_r8(pb) != AMF_DATA_TYPE_STRING)
-return AVERROR_INVALIDDATA;
+while ((ret = amf_get_string(pb, buf, sizeof(buf)))  0) {
+AMFDataType type = avio_r8(pb);
+if (type == AMF_DATA_TYPE_STRING  !strcmp(buf, text)) {
+length = avio_rb16(pb);
+ret= av_get_packet(pb, pkt, length);
+if (ret  0)
+goto skip;
+else
+break;
+} else {
+if ((ret = amf_skip_tag(pb, type))  0)
+goto skip;
+}
+}

-length = avio_rb16(pb);
-ret= av_get_packet(s-pb, pkt, length);
-if (ret  0)
-return AVERROR(EIO);
+if (length  0) {
+ret = AVERROR_INVALIDDATA;
+goto skip;
+}

 for (i = 0; i  s-nb_streams; i++) {
 st = s-streams[i];
@@ -684,6 +731,7 @@ static int flv_data_packet(AVFormatContext *s, AVPacket 
*pkt,
 pkt-stream_index = st-index;
 pkt-flags   |= AV_PKT_FLAG_KEY;

+skip:
 avio_seek(s-pb, next + 4, SEEK_SET);

 return ret;
--
1.8.3.2

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


Re: [libav-devel] [PATCH 1/2] rtmp: Refactor get_packet

2013-09-21 Thread Luca Barbato
On 21/09/13 11:32, Martin Storsjö wrote:
 On Sat, 21 Sep 2013, Luca Barbato wrote:
 
 ---
 libavformat/rtmpproto.c | 119
 +++-
 1 file changed, 57 insertions(+), 62 deletions(-)
 
 The patch itself looks ok to me, one comment further below as note to
 either of us who wants to get to it first.
 
 diff --git a/libavformat/rtmpproto.c b/libavformat/rtmpproto.c
 index a2dffd0..2b2baa3 100644
 --- a/libavformat/rtmpproto.c
 +++ b/libavformat/rtmpproto.c
 @@ -2061,65 +2061,81 @@ static int handle_invoke(URLContext *s,
 RTMPPacket *pkt)
 return ret;
 }

 -static int handle_notify(URLContext *s, RTMPPacket *pkt) {
 -RTMPContext *rt  = s-priv_data;
 -const uint8_t *p = NULL;
 -uint8_t commandbuffer[64];
 -char statusmsg[128];
 -int stringlen;
 -GetByteContext gbc;
 -PutByteContext pbc;
 -uint32_t ts;
 -int old_flv_size, err;
 -const uint8_t *datatowrite;
 -unsigned datatowritelength;
 -
 -p = pkt-data;
 -bytestream2_init(gbc, p, pkt-size);
 -if (ff_amf_read_string(gbc, commandbuffer, sizeof(commandbuffer),
 -   stringlen))
 -return AVERROR_INVALIDDATA;
 -if (!strcmp(commandbuffer, @setDataFrame)) {
 -datatowrite   = gbc.buffer;
 -datatowritelength = bytestream2_get_bytes_left(gbc);
 -if (ff_amf_read_string(gbc, statusmsg,
 -   sizeof(statusmsg), stringlen))
 -return AVERROR_INVALIDDATA;
 -} else {
 -datatowrite   = pkt-data;
 -datatowritelength = pkt-size;
 -}
 -
 -/* Provide ECMAArray to flv */
 -ts = pkt-timestamp;
 +static int update_offset(RTMPContext *rt, int size)
 +{
 +int old_flv_size;

 // generate packet header and put data into buffer for FLV demuxer
 if (rt-flv_off  rt-flv_size) {
 // There is old unread data in the buffer, thus append at the end
 old_flv_size  = rt-flv_size;
 -rt-flv_size += datatowritelength + 15;
 +rt-flv_size += size + 15;
 } else {
 // All data has been read, write the new data at the start of
 the buffer
 old_flv_size = 0;
 -rt-flv_size = datatowritelength + 15;
 +rt-flv_size = size + 15;
 rt-flv_off  = 0;
 }

 -if ((err = av_reallocp(rt-flv_data, rt-flv_size))  0)
 -return err;
 +return old_flv_size;
 +}
 +
 +static int append_flv_data(RTMPContext *rt, RTMPPacket *pkt, int skip)
 +{
 +int old_flv_size, ret;
 +PutByteContext pbc;
 +const uint8_t *data = pkt-data + skip;
 +const int size  = pkt-size - skip;
 +uint32_t ts = pkt-timestamp;
 +
 +av_log(NULL, AV_LOG_ERROR, Timestamp %d\n,
 +   ts);
 +
 +old_flv_size = update_offset(rt, size);
 +
 +if ((ret = av_reallocp(rt-flv_data, rt-flv_size))  0)
 +return ret;
 
 Not relevant for this patch, but potential future improvement: Don't
 realloc every time, but keep track of the allocation size and check if
 we need to enlarge it at all, so we in practice won't need to do the
 realloc in most calls later.

Would make sense, meanwhile I'll amend this patch not to spew pointless
messages

 +av_log(NULL, AV_LOG_ERROR, Timestamp %d\n,
 +   ts);

lu

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

[libav-devel] [PATCH] flv: Make onTextData parsing robust

2013-09-21 Thread Luca Barbato
Certain streaming servers do not preserve the order of the fields.
---

Now assuming strict arrays do not have a key as string.

 libavformat/flvdec.c | 88 
 1 file changed, 69 insertions(+), 19 deletions(-)

diff --git a/libavformat/flvdec.c b/libavformat/flvdec.c
index b8feeaf..051bdc9 100644
--- a/libavformat/flvdec.c
+++ b/libavformat/flvdec.c
@@ -634,35 +634,84 @@ static void clear_index_entries(AVFormatContext *s, 
int64_t pos)
 }
 }

+static int amf_skip_tag(AVIOContext *pb, AMFDataType type)
+{
+int nb = -1, ret, parse_name = 0;
+
+switch (type) {
+case AMF_DATA_TYPE_NUMBER:
+avio_skip(pb, 8);
+break;
+case AMF_DATA_TYPE_BOOL:
+avio_skip(pb, 1);
+break;
+case AMF_DATA_TYPE_STRING:
+avio_skip(pb, avio_rb16(pb));
+break;
+case AMF_DATA_TYPE_ARRAY:
+parse_name = 1;
+case AMF_DATA_TYPE_MIXEDARRAY:
+avio_skip(pb, 4);
+case AMF_DATA_TYPE_OBJECT:
+while(!pb-eof_reached  (nb  0 || type != AMF_DATA_TYPE_ARRAY)) {
+if (parse_name) {
+int size = avio_rb16(pb);
+if (!size) {
+avio_skip(pb, 1);
+break;
+}
+avio_skip(pb, size);
+}
+if ((ret = amf_skip_tag(pb, avio_r8(pb)))  0)
+return ret;
+}
+break;
+case AMF_DATA_TYPE_NULL:
+case AMF_DATA_TYPE_OBJECT_END:
+break;
+default:
+return AVERROR_INVALIDDATA;
+}
+return 0;
+}
+
 static int flv_data_packet(AVFormatContext *s, AVPacket *pkt,
int64_t dts, int64_t next)
 {
 AVIOContext *pb = s-pb;
 AVStream *st= NULL;
-AMFDataType type;
 char buf[20];
-int ret, i, length;
+int ret = AVERROR_INVALIDDATA;
+int i, length = -1;

-type = avio_r8(pb);
-if (type == AMF_DATA_TYPE_MIXEDARRAY)
+switch (avio_r8(pb)) {
+case AMF_DATA_TYPE_MIXEDARRAY:
 avio_seek(pb, 4, SEEK_CUR);
-else if (type != AMF_DATA_TYPE_OBJECT)
-return AVERROR_INVALIDDATA;
-
-amf_get_string(pb, buf, sizeof(buf));
-if (strcmp(buf, type) || avio_r8(pb) != AMF_DATA_TYPE_STRING)
-return AVERROR_INVALIDDATA;
+case AMF_DATA_TYPE_OBJECT:
+break;
+default:
+goto skip;
+}

-amf_get_string(pb, buf, sizeof(buf));
-// FIXME parse it as codec_id
-amf_get_string(pb, buf, sizeof(buf));
-if (strcmp(buf, text) || avio_r8(pb) != AMF_DATA_TYPE_STRING)
-return AVERROR_INVALIDDATA;
+while ((ret = amf_get_string(pb, buf, sizeof(buf)))  0) {
+AMFDataType type = avio_r8(pb);
+if (type == AMF_DATA_TYPE_STRING  !strcmp(buf, text)) {
+length = avio_rb16(pb);
+ret= av_get_packet(pb, pkt, length);
+if (ret  0)
+goto skip;
+else
+break;
+} else {
+if ((ret = amf_skip_tag(pb, type))  0)
+goto skip;
+}
+}

-length = avio_rb16(pb);
-ret= av_get_packet(s-pb, pkt, length);
-if (ret  0)
-return AVERROR(EIO);
+if (length  0) {
+ret = AVERROR_INVALIDDATA;
+goto skip;
+}

 for (i = 0; i  s-nb_streams; i++) {
 st = s-streams[i];
@@ -684,6 +733,7 @@ static int flv_data_packet(AVFormatContext *s, AVPacket 
*pkt,
 pkt-stream_index = st-index;
 pkt-flags   |= AV_PKT_FLAG_KEY;

+skip:
 avio_seek(s-pb, next + 4, SEEK_SET);

 return ret;
--
1.8.3.2

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


[libav-devel] [PATCH] rtmp: Support AMF_DATA_TYPE_MIXEDARRAY

2013-09-21 Thread Luca Barbato
And fix the AMF_DATA_TYPE_ARRAY parsing while at it.

A MIXEDARRAY type, as the ARRAY, store the number of elements in
an uint32 before the list. The ARRAY is strict and does not have
an OBJECT terminator and keys are implicity, MIXEDARRAY behaves
like an OBJECT type and a different than stated number of element
can be present.
---

Now in line with what we have in flvdec and librtmp.

 libavformat/rtmppkt.c | 43 +++
 1 file changed, 27 insertions(+), 16 deletions(-)

diff --git a/libavformat/rtmppkt.c b/libavformat/rtmppkt.c
index 922ca3e..b4407ea 100644
--- a/libavformat/rtmppkt.c
+++ b/libavformat/rtmppkt.c
@@ -370,28 +370,35 @@ void ff_rtmp_packet_destroy(RTMPPacket *pkt)
 int ff_amf_tag_size(const uint8_t *data, const uint8_t *data_end)
 {
 const uint8_t *base = data;
+AMFDataType type;
+unsigned nb   = -1;
+int parse_key = 1;

 if (data = data_end)
 return -1;
-switch (*data++) {
+switch ((type = *data++)) {
 case AMF_DATA_TYPE_NUMBER:  return 9;
 case AMF_DATA_TYPE_BOOL:return 2;
 case AMF_DATA_TYPE_STRING:  return 3 + AV_RB16(data);
 case AMF_DATA_TYPE_LONG_STRING: return 5 + AV_RB32(data);
 case AMF_DATA_TYPE_NULL:return 1;
 case AMF_DATA_TYPE_ARRAY:
-data += 4;
+parse_key = 0;
+case AMF_DATA_TYPE_MIXEDARRAY:
+nb = bytestream_get_be32(data);
 case AMF_DATA_TYPE_OBJECT:
-for (;;) {
-int size = bytestream_get_be16(data);
+while (nb--  0 || type != AMF_DATA_TYPE_ARRAY) {
 int t;
-if (!size) {
-data++;
-break;
+if (parse_key) {
+int size = bytestream_get_be16(data);
+if (!size) {
+data++;
+break;
+}
+if (size  0 || size = data_end - data)
+return -1;
+data += size;
 }
-if (size  0 || size = data_end - data)
-return -1;
-data += size;
 t = ff_amf_tag_size(data, data_end);
 if (t  0 || t = data_end - data)
 return -1;
@@ -474,12 +481,13 @@ static const char* rtmp_packet_type(int type)
 static void amf_tag_contents(void *ctx, const uint8_t *data,
  const uint8_t *data_end)
 {
-unsigned int size;
+unsigned int size, nb = -1;
 char buf[1024];
+AMFDataType type;

 if (data = data_end)
 return;
-switch (*data++) {
+switch ((type = *data++)) {
 case AMF_DATA_TYPE_NUMBER:
 av_log(ctx, AV_LOG_DEBUG,  number %g\n, 
av_int2double(AV_RB64(data)));
 return;
@@ -488,7 +496,7 @@ static void amf_tag_contents(void *ctx, const uint8_t *data,
 return;
 case AMF_DATA_TYPE_STRING:
 case AMF_DATA_TYPE_LONG_STRING:
-if (data[-1] == AMF_DATA_TYPE_STRING) {
+if (type == AMF_DATA_TYPE_STRING) {
 size = bytestream_get_be16(data);
 } else {
 size = bytestream_get_be32(data);
@@ -501,19 +509,22 @@ static void amf_tag_contents(void *ctx, const uint8_t 
*data,
 case AMF_DATA_TYPE_NULL:
 av_log(ctx, AV_LOG_DEBUG,  NULL\n);
 return;
+case AMF_DATA_TYPE_MIXEDARRAY:
 case AMF_DATA_TYPE_ARRAY:
-data += 4;
+nb = bytestream_get_be32(data);
 case AMF_DATA_TYPE_OBJECT:
 av_log(ctx, AV_LOG_DEBUG,  {\n);
-for (;;) {
+while (nb--  0 || type != AMF_DATA_TYPE_ARRAY) {
 int t;
 size = bytestream_get_be16(data);
-av_strlcpy(buf, data, FFMIN(sizeof(buf), size + 1));
+size = FFMIN(size, sizeof(buf) - 1);
 if (!size) {
 av_log(ctx, AV_LOG_DEBUG,  }\n);
 data++;
 break;
 }
+memcpy(buf, data, size);
+buf[size] = 0;
 if (size = data_end - data)
 return;
 data += size;
--
1.8.3.2

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


Re: [libav-devel] [PATCH] flv: Make onTextData parsing robust

2013-09-21 Thread Luca Barbato
On 21/09/13 11:47, Luca Barbato wrote:
 Certain streaming servers do not preserve the order of the fields.
 ---
 
 Now assuming strict arrays do not have a key as string.
 

Locally amended to have 0 and 1 flipped =P

lu

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


Re: [libav-devel] [PATCH 2/2] rtmp: Refactor get_packet (part 2)

2013-09-21 Thread Martin Storsjö

On Sat, 21 Sep 2013, Luca Barbato wrote:


---
libavformat/rtmpproto.c | 69 +
1 file changed, 41 insertions(+), 28 deletions(-)


Probably ok. As far as I can see, this is just moving the existing code 
into a separate function and changing it to use update_offset?


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


Re: [libav-devel] [PATCH] rtmp: Support AMF_DATA_TYPE_MIXEDARRAY

2013-09-21 Thread Martin Storsjö

On Sat, 21 Sep 2013, Luca Barbato wrote:


And fix the AMF_DATA_TYPE_ARRAY parsing while at it.

A MIXEDARRAY type, as the ARRAY, store the number of elements in
an uint32 before the list. The ARRAY is strict and does not have
an OBJECT terminator and keys are implicity, MIXEDARRAY behaves
like an OBJECT type and a different than stated number of element
can be present.
---

Now in line with what we have in flvdec and librtmp.

libavformat/rtmppkt.c | 43 +++
1 file changed, 27 insertions(+), 16 deletions(-)

diff --git a/libavformat/rtmppkt.c b/libavformat/rtmppkt.c
index 922ca3e..b4407ea 100644
--- a/libavformat/rtmppkt.c
+++ b/libavformat/rtmppkt.c
@@ -370,28 +370,35 @@ void ff_rtmp_packet_destroy(RTMPPacket *pkt)
int ff_amf_tag_size(const uint8_t *data, const uint8_t *data_end)
{
const uint8_t *base = data;
+AMFDataType type;
+unsigned nb   = -1;
+int parse_key = 1;

if (data = data_end)
return -1;
-switch (*data++) {
+switch ((type = *data++)) {
case AMF_DATA_TYPE_NUMBER:  return 9;
case AMF_DATA_TYPE_BOOL:return 2;
case AMF_DATA_TYPE_STRING:  return 3 + AV_RB16(data);
case AMF_DATA_TYPE_LONG_STRING: return 5 + AV_RB32(data);
case AMF_DATA_TYPE_NULL:return 1;
case AMF_DATA_TYPE_ARRAY:
-data += 4;
+parse_key = 0;
+case AMF_DATA_TYPE_MIXEDARRAY:
+nb = bytestream_get_be32(data);
case AMF_DATA_TYPE_OBJECT:
-for (;;) {
-int size = bytestream_get_be16(data);
+while (nb--  0 || type != AMF_DATA_TYPE_ARRAY) {
int t;
-if (!size) {
-data++;
-break;
+if (parse_key) {
+int size = bytestream_get_be16(data);
+if (!size) {
+data++;
+break;
+}
+if (size  0 || size = data_end - data)
+return -1;
+data += size;
}
-if (size  0 || size = data_end - data)
-return -1;
-data += size;
t = ff_amf_tag_size(data, data_end);
if (t  0 || t = data_end - data)
return -1;


This part looks good


@@ -474,12 +481,13 @@ static const char* rtmp_packet_type(int type)
static void amf_tag_contents(void *ctx, const uint8_t *data,
 const uint8_t *data_end)
{
-unsigned int size;
+unsigned int size, nb = -1;
char buf[1024];
+AMFDataType type;

if (data = data_end)
return;
-switch (*data++) {
+switch ((type = *data++)) {
case AMF_DATA_TYPE_NUMBER:
av_log(ctx, AV_LOG_DEBUG,  number %g\n, av_int2double(AV_RB64(data)));
return;
@@ -488,7 +496,7 @@ static void amf_tag_contents(void *ctx, const uint8_t *data,
return;
case AMF_DATA_TYPE_STRING:
case AMF_DATA_TYPE_LONG_STRING:
-if (data[-1] == AMF_DATA_TYPE_STRING) {
+if (type == AMF_DATA_TYPE_STRING) {
size = bytestream_get_be16(data);
} else {
size = bytestream_get_be32(data);
@@ -501,19 +509,22 @@ static void amf_tag_contents(void *ctx, const uint8_t 
*data,
case AMF_DATA_TYPE_NULL:
av_log(ctx, AV_LOG_DEBUG,  NULL\n);
return;
+case AMF_DATA_TYPE_MIXEDARRAY:
case AMF_DATA_TYPE_ARRAY:
-data += 4;
+nb = bytestream_get_be32(data);
case AMF_DATA_TYPE_OBJECT:
av_log(ctx, AV_LOG_DEBUG,  {\n);
-for (;;) {
+while (nb--  0 || type != AMF_DATA_TYPE_ARRAY) {
int t;
size = bytestream_get_be16(data);


This still seems to look for strings in plain arrays.

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


Re: [libav-devel] [PATCH] flv: Make onTextData parsing robust

2013-09-21 Thread Martin Storsjö

On Sat, 21 Sep 2013, Luca Barbato wrote:


On 21/09/13 11:47, Luca Barbato wrote:

Certain streaming servers do not preserve the order of the fields.
---

Now assuming strict arrays do not have a key as string.



Locally amended to have 0 and 1 flipped =P


Probably ok with that fixed.

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


Re: [libav-devel] [PATCH 2/2] rtmp: Refactor get_packet (part 2)

2013-09-21 Thread Luca Barbato
On 21/09/13 12:11, Martin Storsjö wrote:
 On Sat, 21 Sep 2013, Luca Barbato wrote:
 
 ---
 libavformat/rtmpproto.c | 69
 +
 1 file changed, 41 insertions(+), 28 deletions(-)
 
 Probably ok. As far as I can see, this is just moving the existing code
 into a separate function and changing it to use update_offset?
 

Before it was writing over the packet and then copying, now it copies as
it goes reading.

This way we do not have a warning and the code seems slightly uniform
with the rest.

lu

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

[libav-devel] [PATCH] rtmp: Support AMF_DATA_TYPE_MIXEDARRAY

2013-09-21 Thread Luca Barbato
And fix the AMF_DATA_TYPE_ARRAY parsing while at it.

A MIXEDARRAY type, as the ARRAY, store the number of elements in
an uint32 before the list. The ARRAY is strict and does not have
an OBJECT terminator, MIXEDARRAY behaves like an OBJECT type and
a different than stated number of element can be present.
---

Before I forgot amf_tag_contents...

 libavformat/rtmppkt.c | 65 +++
 1 file changed, 40 insertions(+), 25 deletions(-)

diff --git a/libavformat/rtmppkt.c b/libavformat/rtmppkt.c
index 922ca3e..defe81e 100644
--- a/libavformat/rtmppkt.c
+++ b/libavformat/rtmppkt.c
@@ -370,28 +370,35 @@ void ff_rtmp_packet_destroy(RTMPPacket *pkt)
 int ff_amf_tag_size(const uint8_t *data, const uint8_t *data_end)
 {
 const uint8_t *base = data;
+AMFDataType type;
+unsigned nb   = -1;
+int parse_key = 1;

 if (data = data_end)
 return -1;
-switch (*data++) {
+switch ((type = *data++)) {
 case AMF_DATA_TYPE_NUMBER:  return 9;
 case AMF_DATA_TYPE_BOOL:return 2;
 case AMF_DATA_TYPE_STRING:  return 3 + AV_RB16(data);
 case AMF_DATA_TYPE_LONG_STRING: return 5 + AV_RB32(data);
 case AMF_DATA_TYPE_NULL:return 1;
 case AMF_DATA_TYPE_ARRAY:
-data += 4;
+parse_key = 0;
+case AMF_DATA_TYPE_MIXEDARRAY:
+nb = bytestream_get_be32(data);
 case AMF_DATA_TYPE_OBJECT:
-for (;;) {
-int size = bytestream_get_be16(data);
+while (nb--  0 || type != AMF_DATA_TYPE_ARRAY) {
 int t;
-if (!size) {
-data++;
-break;
+if (parse_key) {
+int size = bytestream_get_be16(data);
+if (!size) {
+data++;
+break;
+}
+if (size  0 || size = data_end - data)
+return -1;
+data += size;
 }
-if (size  0 || size = data_end - data)
-return -1;
-data += size;
 t = ff_amf_tag_size(data, data_end);
 if (t  0 || t = data_end - data)
 return -1;
@@ -474,12 +481,14 @@ static const char* rtmp_packet_type(int type)
 static void amf_tag_contents(void *ctx, const uint8_t *data,
  const uint8_t *data_end)
 {
-unsigned int size;
+unsigned int size, nb = -1;
 char buf[1024];
+AMFDataType type;
+int parse_key = 1;

 if (data = data_end)
 return;
-switch (*data++) {
+switch ((type = *data++)) {
 case AMF_DATA_TYPE_NUMBER:
 av_log(ctx, AV_LOG_DEBUG,  number %g\n, 
av_int2double(AV_RB64(data)));
 return;
@@ -488,7 +497,7 @@ static void amf_tag_contents(void *ctx, const uint8_t *data,
 return;
 case AMF_DATA_TYPE_STRING:
 case AMF_DATA_TYPE_LONG_STRING:
-if (data[-1] == AMF_DATA_TYPE_STRING) {
+if (type == AMF_DATA_TYPE_STRING) {
 size = bytestream_get_be16(data);
 } else {
 size = bytestream_get_be32(data);
@@ -502,22 +511,28 @@ static void amf_tag_contents(void *ctx, const uint8_t 
*data,
 av_log(ctx, AV_LOG_DEBUG,  NULL\n);
 return;
 case AMF_DATA_TYPE_ARRAY:
-data += 4;
+parse_key = 0;
+case AMF_DATA_TYPE_MIXEDARRAY:
+nb = bytestream_get_be32(data);
 case AMF_DATA_TYPE_OBJECT:
 av_log(ctx, AV_LOG_DEBUG,  {\n);
-for (;;) {
+while (nb--  0 || type != AMF_DATA_TYPE_ARRAY) {
 int t;
-size = bytestream_get_be16(data);
-av_strlcpy(buf, data, FFMIN(sizeof(buf), size + 1));
-if (!size) {
-av_log(ctx, AV_LOG_DEBUG,  }\n);
-data++;
-break;
+if (parse_key) {
+size = bytestream_get_be16(data);
+size = FFMIN(size, sizeof(buf) - 1);
+if (!size) {
+av_log(ctx, AV_LOG_DEBUG,  }\n);
+data++;
+break;
+}
+memcpy(buf, data, size);
+buf[size] = 0;
+if (size = data_end - data)
+return;
+data += size;
+av_log(ctx, AV_LOG_DEBUG,   %s: , buf);
 }
-if (size = data_end - data)
-return;
-data += size;
-av_log(ctx, AV_LOG_DEBUG,   %s: , buf);
 amf_tag_contents(ctx, data, data_end);
 t = ff_amf_tag_size(data, data_end);
 if (t  0 || t = data_end - data)
--
1.8.3.2

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


Re: [libav-devel] [PATCH] rtmp: Support AMF_DATA_TYPE_MIXEDARRAY

2013-09-21 Thread Martin Storsjö

On Sat, 21 Sep 2013, Luca Barbato wrote:


And fix the AMF_DATA_TYPE_ARRAY parsing while at it.

A MIXEDARRAY type, as the ARRAY, store the number of elements in
an uint32 before the list. The ARRAY is strict and does not have
an OBJECT terminator, MIXEDARRAY behaves like an OBJECT type and
a different than stated number of element can be present.
---

Before I forgot amf_tag_contents...

libavformat/rtmppkt.c | 65 +++
1 file changed, 40 insertions(+), 25 deletions(-)


Now it's probably ok I guess.

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


[libav-devel] [PATCH] avutil: Fix compilation with inline asm disabled on mingw

2013-09-21 Thread Alex Smith
Because of -Werror=implicit-function-declaration the build will fail.
---
 libavutil/x86/timer.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/libavutil/x86/timer.h b/libavutil/x86/timer.h
index 35e614d..cdd67dd 100644
--- a/libavutil/x86/timer.h
+++ b/libavutil/x86/timer.h
@@ -36,6 +36,7 @@ static inline uint64_t read_time(void)
 
 #elif HAVE_RDTSC
 
+#include intrin.h
 #define AV_READ_TIME __rdtsc
 
 #endif /* HAVE_INLINE_ASM */
-- 
1.8.4.msysgit.0

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


Re: [libav-devel] [PATCH] avutil: Fix compilation with inline asm disabled on mingw

2013-09-21 Thread Luca Barbato
On 21/09/13 13:22, Alex Smith wrote:
 Because of -Werror=implicit-function-declaration the build will fail.
 ---
  libavutil/x86/timer.h | 1 +
  1 file changed, 1 insertion(+)
 

Looks fine to me.

lu

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


[libav-devel] Next point releases

2013-09-21 Thread Luca Barbato
Hi, I'd like to have a new 0.8 release and given the number of fixes we
collected in those weeks (thanks Martin for taking that task) probably
also a 9.10 might be a good idea.

I kept forwarding to 0.8 some patches, help would be welcome since most
of them conflict so it is quite boring doing that for a bulk even if
forwarding just a single one takes about 5 minutes.

Forwarding to release 9 is straightforward so it isn't as annoying,
still help would be welcome even in that case.

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


Re: [libav-devel] [PATCH] Add interleaved 4:2:2 8/10-bit formats

2013-09-21 Thread Luca Barbato
On 17/09/13 23:30, Kieran Kunhya wrote:
 ---
  libavutil/pixdesc.c |   36 
  libavutil/pixfmt.h  |4 
  2 files changed, 40 insertions(+)
 

Looks fine to me.

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


Re: [libav-devel] [PATCH] dirac decoder

2013-09-21 Thread Vittorio Giovara
On Mon, Sep 16, 2013 at 11:35 AM, Luca Barbato lu_z...@gentoo.org wrote:
 On 22/01/13 20:30, Jordi Ortiz wrote:
 Thanks for the review

 What is the status of this decoder now?  Does it still produce artifacts?
 If yes, for which cases?

 The status is the same as it was. When sub pixel motion vector precision
 is used the decoded result isn't bit exact with last libschroedinger
 version.
 Also deep-estimation is not working properly. If anyone knows what
 deep-estimation is and wants to point it out it would be very welcome, I
 didn't manage to find any reference in the standard. I know that deep
 estimation uses mv_precision values over zero so the problem in this
 case could be related to the mv_precision.

 Let's just document that and add some avpriv_report_missing_feature.

 Would be nice having it in some shape this year.

I do agree, Jordi think that you could send an updated patch with the
latest changes?
Thank you,
Vittorio
___
libav-devel mailing list
libav-devel@libav.org
https://lists.libav.org/mailman/listinfo/libav-devel


[libav-devel] [PATCH] lavu: Add interleaved 4:2:2 8/10-bit formats

2013-09-21 Thread Luca Barbato
From: Kieran Kunhya kier...@ob-encoder.com

Signed-off-by: Luca Barbato lu_z...@gentoo.org
---

I'd also bump the version.

 doc/APIchanges  |  4 
 libavutil/pixdesc.c | 36 
 libavutil/pixfmt.h  |  4 
 libavutil/version.h |  2 +-
 4 files changed, 45 insertions(+), 1 deletion(-)

diff --git a/doc/APIchanges b/doc/APIchanges
index fbd3ff9..85c02d6 100644
--- a/doc/APIchanges
+++ b/doc/APIchanges
@@ -13,6 +13,10 @@ libavutil: 2012-10-22

 API changes, most recent first:

+2013-09-21 - xxx - lavu 52.16.0 - pixfmt.h
+  Add interleaved 4:2:2 8/10-bit formats AV_PIX_FMT_NV16 and
+  AV_PIX_FMT_NV20.
+
 2013-09-16 - 3feb3d6 - lavu 52.15.0 - mem.h
   Add av_reallocp.

diff --git a/libavutil/pixdesc.c b/libavutil/pixdesc.c
index 3ac5785..c44bc16 100644
--- a/libavutil/pixdesc.c
+++ b/libavutil/pixdesc.c
@@ -1392,6 +1392,42 @@ const AVPixFmtDescriptor 
av_pix_fmt_descriptors[AV_PIX_FMT_NB] = {
},
 .flags = AV_PIX_FMT_FLAG_BE,
 },
+[AV_PIX_FMT_NV16] = {
+.name = nv16,
+.nb_components = 3,
+.log2_chroma_w = 1,
+.log2_chroma_h = 0,
+.comp = {
+{ 0, 0, 1, 0, 7 },/* Y */
+{ 1, 1, 1, 0, 7 },/* U */
+{ 1, 1, 2, 0, 7 },/* V */
+},
+.flags = AV_PIX_FMT_FLAG_PLANAR,
+},
+[AV_PIX_FMT_NV20LE] = {
+.name = nv20le,
+.nb_components = 3,
+.log2_chroma_w = 1,
+.log2_chroma_h = 0,
+.comp = {
+{ 0, 0, 1, 0, 9 },/* Y */
+{ 1, 1, 1, 0, 9 },/* U */
+{ 1, 1, 3, 0, 9 },/* V */
+},
+.flags = AV_PIX_FMT_FLAG_PLANAR,
+},
+[AV_PIX_FMT_NV20BE] = {
+.name = nv20be,
+.nb_components = 3,
+.log2_chroma_w = 1,
+.log2_chroma_h = 0,
+.comp = {
+{ 0, 0, 1, 0, 9 },/* Y */
+{ 1, 1, 1, 0, 9 },/* U */
+{ 1, 1, 3, 0, 9 },/* V */
+},
+.flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_BE,
+},
 };

 FF_DISABLE_DEPRECATION_WARNINGS
diff --git a/libavutil/pixfmt.h b/libavutil/pixfmt.h
index 4b04944..43633e7 100644
--- a/libavutil/pixfmt.h
+++ b/libavutil/pixfmt.h
@@ -185,6 +185,9 @@ enum AVPixelFormat {
 AV_PIX_FMT_VDPAU, /// HW acceleration through VDPAU, Picture.data[3] 
contains a VdpVideoSurface
 AV_PIX_FMT_XYZ12LE,  /// packed XYZ 4:4:4, 36 bpp, (msb) 12X, 12Y, 
12Z (lsb), the 2-byte value for each X/Y/Z is stored as little-endian, the 4 
lower bits are set to 0
 AV_PIX_FMT_XYZ12BE,  /// packed XYZ 4:4:4, 36 bpp, (msb) 12X, 12Y, 
12Z (lsb), the 2-byte value for each X/Y/Z is stored as big-endian, the 4 lower 
bits are set to 0
+AV_PIX_FMT_NV16, /// interleaved chroma YUV 4:2:2, 16bpp, (1 Cr  
Cb sample per 2x1 Y samples)
+AV_PIX_FMT_NV20LE,   /// interleaved chroma YUV 4:2:2, 20bpp, (1 Cr  
Cb sample per 2x1 Y samples), little-endian
+AV_PIX_FMT_NV20BE,   /// interleaved chroma YUV 4:2:2, 20bpp, (1 Cr  
Cb sample per 2x1 Y samples), big-endian
 AV_PIX_FMT_NB,/// number of pixel formats, DO NOT USE THIS if you 
want to link with shared libav* because the number of formats might differ 
between versions

 #if FF_API_PIX_FMT
@@ -238,6 +241,7 @@ enum AVPixelFormat {
 #define AV_PIX_FMT_YUVA444P16 AV_PIX_FMT_NE(YUVA444P16BE, YUVA444P16LE)

 #define AV_PIX_FMT_XYZ12  AV_PIX_FMT_NE(XYZ12BE, XYZ12LE)
+#define AV_PIX_FMT_NV20   AV_PIX_FMT_NE(NV20BE,  NV20LE)

 #if FF_API_PIX_FMT
 #define PixelFormat AVPixelFormat
diff --git a/libavutil/version.h b/libavutil/version.h
index 935c505..635055f 100644
--- a/libavutil/version.h
+++ b/libavutil/version.h
@@ -37,7 +37,7 @@
  */

 #define LIBAVUTIL_VERSION_MAJOR 52
-#define LIBAVUTIL_VERSION_MINOR 15
+#define LIBAVUTIL_VERSION_MINOR 16
 #define LIBAVUTIL_VERSION_MICRO  0

 #define LIBAVUTIL_VERSION_INT   AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \
--
1.8.3.2

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


[libav-devel] [PATCH] avcodec: Use av_reallocp where suitable

2013-09-21 Thread Alexandra Khirnova
---
 libavcodec/binkaudio.c|9 +
 libavcodec/bitstream.c|   10 +++---
 libavcodec/flashsv.c  |   10 ++
 libavcodec/g2meet.c   |8 +++-
 libavcodec/h264_mp4toannexb_bsf.c |   19 +++
 libavcodec/libmp3lame.c   |   10 +++---
 libavcodec/libschroedingerenc.c   |7 +--
 libavcodec/libtheoraenc.c |9 +++--
 libavcodec/libvpxenc.c|9 +
 libavcodec/shorten.c  |   27 ++-
 libavcodec/utils.c|5 +++--
 libavcodec/zmbv.c |   15 +++
 12 files changed, 64 insertions(+), 74 deletions(-)

diff --git a/libavcodec/binkaudio.c b/libavcodec/binkaudio.c
index d49964b..8c8b722 100644
--- a/libavcodec/binkaudio.c
+++ b/libavcodec/binkaudio.c
@@ -294,6 +294,7 @@ static int decode_frame(AVCodecContext *avctx, void *data,
 
 if (!get_bits_left(gb)) {
 uint8_t *buf;
+int err;
 /* handle end-of-stream */
 if (!avpkt-size) {
 *got_frame_ptr = 0;
@@ -303,10 +304,10 @@ static int decode_frame(AVCodecContext *avctx, void *data,
 av_log(avctx, AV_LOG_ERROR, Packet is too small\n);
 return AVERROR_INVALIDDATA;
 }
-buf = av_realloc(s-packet_buffer, avpkt-size + 
FF_INPUT_BUFFER_PADDING_SIZE);
-if (!buf)
-return AVERROR(ENOMEM);
-s-packet_buffer = buf;
+if ((err = av_reallocp(s-packet_buffer,
+   avpkt-size +
+   FF_INPUT_BUFFER_PADDING_SIZE))  0)
+return err;
 memcpy(s-packet_buffer, avpkt-data, avpkt-size);
 init_get_bits(gb, s-packet_buffer, avpkt-size * 8);
 consumed = avpkt-size;
diff --git a/libavcodec/bitstream.c b/libavcodec/bitstream.c
index 197e07f..9d82ad6 100644
--- a/libavcodec/bitstream.c
+++ b/libavcodec/bitstream.c
@@ -106,12 +106,16 @@ static int alloc_table(VLC *vlc, int size, int use_static)
 
 vlc-table_size += size;
 if (vlc-table_size  vlc-table_allocated) {
+int err;
 if (use_static)
 return AVERROR_BUG;
 vlc-table_allocated += (1  vlc-bits);
-vlc-table = av_realloc(vlc-table, sizeof(VLC_TYPE) * 2 * 
vlc-table_allocated);
-if (!vlc-table)
-return AVERROR(ENOMEM);
+if ((err = av_reallocp(vlc-table,
+   sizeof(VLC_TYPE) * 2 *
+   vlc-table_allocated))  0) {
+vlc-table_allocated = 0;
+return err;
+}
 }
 return index;
 }
diff --git a/libavcodec/flashsv.c b/libavcodec/flashsv.c
index 2fbe221..ff74e23 100644
--- a/libavcodec/flashsv.c
+++ b/libavcodec/flashsv.c
@@ -317,11 +317,13 @@ static int flashsv_decode_frame(AVCodecContext *avctx, 
void *data,
 /* we care for keyframes only in Screen Video v2 */
 s-is_keyframe = (avpkt-flags  AV_PKT_FLAG_KEY)  (s-ver == 2);
 if (s-is_keyframe) {
-s-keyframedata = av_realloc(s-keyframedata, avpkt-size);
+int err;
+if ((err = av_reallocp(s-keyframedata, avpkt-size))  0)
+return err;
 memcpy(s-keyframedata, avpkt-data, avpkt-size);
-s-blocks = av_realloc(s-blocks,
-   (v_blocks + !!v_part) * (h_blocks + !!h_part)
-   * sizeof(s-blocks[0]));
+if ((err = av_reallocp(s-blocks, (v_blocks + !!v_part) *
+   (h_blocks + !!h_part) * sizeof(s-blocks[0]))) 
 0)
+return err;
 }
 
 av_dlog(avctx, image: %dx%d block: %dx%d num: %dx%d part: %dx%d\n,
diff --git a/libavcodec/g2meet.c b/libavcodec/g2meet.c
index 1bbac2d..1c8bf8d 100644
--- a/libavcodec/g2meet.c
+++ b/libavcodec/g2meet.c
@@ -236,16 +236,14 @@ static int jpg_decode_data(JPGContext *c, int width, int 
height,
int swapuv)
 {
 GetBitContext gb;
-uint8_t *tmp;
 int mb_w, mb_h, mb_x, mb_y, i, j;
 int bx, by;
 int unesc_size;
 int ret;
 
-tmp = av_realloc(c-buf, src_size + FF_INPUT_BUFFER_PADDING_SIZE);
-if (!tmp)
-return AVERROR(ENOMEM);
-c-buf = tmp;
+if ((ret = av_reallocp(c-buf,
+   src_size + FF_INPUT_BUFFER_PADDING_SIZE))  0)
+return ret;
 jpg_unescape(src, src_size, c-buf, unesc_size);
 memset(c-buf + unesc_size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
 init_get_bits(gb, c-buf, unesc_size * 8);
diff --git a/libavcodec/h264_mp4toannexb_bsf.c 
b/libavcodec/h264_mp4toannexb_bsf.c
index e86c3e1..9e8115d 100644
--- a/libavcodec/h264_mp4toannexb_bsf.c
+++ b/libavcodec/h264_mp4toannexb_bsf.c
@@ -37,13 +37,12 @@ static int alloc_and_copy(uint8_t **poutbuf, int 
*poutbuf_size,
 {
 uint32_t offset = *poutbuf_size;
 uint8_t nal_header_size = offset ? 3 : 4;
-void *tmp;
+int err;
 
 *poutbuf_size += sps_pps_size + in_size + 

Re: [libav-devel] [PATCH] flv: Make onTextData parsing robust

2013-09-21 Thread Josh Allmann
On 21 September 2013 02:47, Luca Barbato lu_z...@gentoo.org wrote:
 Certain streaming servers do not preserve the order of the fields.
 ---

 Now assuming strict arrays do not have a key as string.

  libavformat/flvdec.c | 88 
 
  1 file changed, 69 insertions(+), 19 deletions(-)

 diff --git a/libavformat/flvdec.c b/libavformat/flvdec.c
 index b8feeaf..051bdc9 100644
 --- a/libavformat/flvdec.c
 +++ b/libavformat/flvdec.c
 @@ -634,35 +634,84 @@ static void clear_index_entries(AVFormatContext *s, 
 int64_t pos)
  }
  }

 +static int amf_skip_tag(AVIOContext *pb, AMFDataType type)
 +{
 +int nb = -1, ret, parse_name = 0;
 +
 +switch (type) {
 +case AMF_DATA_TYPE_NUMBER:
 +avio_skip(pb, 8);
 +break;
 +case AMF_DATA_TYPE_BOOL:
 +avio_skip(pb, 1);
 +break;
 +case AMF_DATA_TYPE_STRING:
 +avio_skip(pb, avio_rb16(pb));
 +break;
 +case AMF_DATA_TYPE_ARRAY:
 +parse_name = 1;
 +case AMF_DATA_TYPE_MIXEDARRAY:
 +avio_skip(pb, 4);
 +case AMF_DATA_TYPE_OBJECT:
 +while(!pb-eof_reached  (nb  0 || type != AMF_DATA_TYPE_ARRAY)) {

nb is never set; it will always be -1.

 +if (parse_name) {

This will never be hit the way the code is currently written. The
parse_name conditions also look mixed up; probably it should default
to 1 and be set to 0 for plain arrays.
___
libav-devel mailing list
libav-devel@libav.org
https://lists.libav.org/mailman/listinfo/libav-devel


Re: [libav-devel] [PATCH] rtmp: Support AMF_DATA_TYPE_MIXEDARRAY

2013-09-21 Thread Josh Allmann
On 21 September 2013 04:03, Martin Storsjö mar...@martin.st wrote:
 On Sat, 21 Sep 2013, Luca Barbato wrote:

 And fix the AMF_DATA_TYPE_ARRAY parsing while at it.

 A MIXEDARRAY type, as the ARRAY, store the number of elements in
 an uint32 before the list. The ARRAY is strict and does not have
 an OBJECT terminator, MIXEDARRAY behaves like an OBJECT type and
 a different than stated number of element can be present.
 ---

 Before I forgot amf_tag_contents...

 libavformat/rtmppkt.c | 65
 +++
 1 file changed, 40 insertions(+), 25 deletions(-)


 Now it's probably ok I guess.


This one looks OK to me too.
___
libav-devel mailing list
libav-devel@libav.org
https://lists.libav.org/mailman/listinfo/libav-devel


Re: [libav-devel] [PATCH 2/2] rtmp: Refactor get_packet (part 2)

2013-09-21 Thread Josh Allmann
On 21 September 2013 02:11, Luca Barbato lu_z...@gentoo.org wrote:
 ---
  libavformat/rtmpproto.c | 69 
 +
  1 file changed, 41 insertions(+), 28 deletions(-)

 diff --git a/libavformat/rtmpproto.c b/libavformat/rtmpproto.c
 index 2b2baa3..da84254 100644
 --- a/libavformat/rtmpproto.c
 +++ b/libavformat/rtmpproto.c
 @@ -2187,6 +2187,46 @@ static int rtmp_parse_result(URLContext *s, 
 RTMPContext *rt, RTMPPacket *pkt)
  return 0;
  }

 +static int handle_metadata(RTMPContext *rt, RTMPPacket *pkt)
 +{
 +int ret, old_flv_size;
 +const uint8_t *next;
 +uint8_t *p;
 +uint32_t size;
 +uint32_t ts, cts, pts = 0;
 +
 +old_flv_size = update_offset(rt, pkt-size);
 +
 +if ((ret = av_reallocp(rt-flv_data, rt-flv_size))  0)
 +return ret;
 +
 +next = pkt-data;
 +p= rt-flv_data + old_flv_size;
 +
 +/* rewrite timestamps */

/* copy data while rewriting timestamps */
might be more accurate

 +ts = pkt-timestamp;
 +while (next - pkt-data  pkt-size - 11) {

The number 11 here is magic, maybe a comment explaining this is
supposed to be the length of a header?

 +*p++ = *next++;
 +size = bytestream_get_be24(next);
 +bytestream_put_be24(p, size);

Group this with bytestream_put_be24(p, ts), just for consistency?

Please elaborate on these changes in the commit message also
(since this seems like a bit more than a refactor to shuffle code around)

Maybe something like this:

rtmp: Handle metadata outside get_packet

Use update_offset(), and also copy the data while rewriting
timestamps, rather than overwriting the old timestamps then copying.

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


Re: [libav-devel] [PATCH 2/2] rtmp: Refactor get_packet (part 2)

2013-09-21 Thread Luca Barbato
On 21/09/13 20:50, Josh Allmann wrote:
 On 21 September 2013 02:11, Luca Barbato lu_z...@gentoo.org wrote:
 ---
  libavformat/rtmpproto.c | 69 
 +
  1 file changed, 41 insertions(+), 28 deletions(-)

 diff --git a/libavformat/rtmpproto.c b/libavformat/rtmpproto.c
 index 2b2baa3..da84254 100644
 --- a/libavformat/rtmpproto.c
 +++ b/libavformat/rtmpproto.c
 @@ -2187,6 +2187,46 @@ static int rtmp_parse_result(URLContext *s, 
 RTMPContext *rt, RTMPPacket *pkt)
  return 0;
  }

 +static int handle_metadata(RTMPContext *rt, RTMPPacket *pkt)
 +{
 +int ret, old_flv_size;
 +const uint8_t *next;
 +uint8_t *p;
 +uint32_t size;
 +uint32_t ts, cts, pts = 0;
 +
 +old_flv_size = update_offset(rt, pkt-size);
 +
 +if ((ret = av_reallocp(rt-flv_data, rt-flv_size))  0)
 +return ret;
 +
 +next = pkt-data;
 +p= rt-flv_data + old_flv_size;
 +
 +/* rewrite timestamps */
 
 /* copy data while rewriting timestamps */
 might be more accurate
 
 +ts = pkt-timestamp;
 +while (next - pkt-data  pkt-size - 11) {
 
 The number 11 here is magic, maybe a comment explaining this is
 supposed to be the length of a header?
 
 +*p++ = *next++;
 +size = bytestream_get_be24(next);
 +bytestream_put_be24(p, size);
 
 Group this with bytestream_put_be24(p, ts), just for consistency?

Either you read and write each field (as I do now) or you
try to read all the bits and then write.

Not sure which is more consistent.

 Please elaborate on these changes in the commit message also
 (since this seems like a bit more than a refactor to shuffle code around)
 
 Maybe something like this:
 
 rtmp: Handle metadata outside get_packet
 
 Use update_offset(), and also copy the data while rewriting
 timestamps, rather than overwriting the old timestamps then copying.

I'll be more verbose indeed =)

lu

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


[libav-devel] [PATCH 4/5] rtmp: Rewrite embedded flv handling

2013-09-21 Thread Luca Barbato
Use update_offset() as done for rtmp audio, video and notifications and
read update and write the fields instead of replacing them in the rtmp
packet and then memcpying it to the output buffer.
---
 libavformat/rtmpproto.c | 70 +
 1 file changed, 42 insertions(+), 28 deletions(-)

diff --git a/libavformat/rtmpproto.c b/libavformat/rtmpproto.c
index 5a0bd7a..deaef23 100644
--- a/libavformat/rtmpproto.c
+++ b/libavformat/rtmpproto.c
@@ -2184,6 +2184,47 @@ static int rtmp_parse_result(URLContext *s, RTMPContext 
*rt, RTMPPacket *pkt)
 return 0;
 }
 
+static int handle_metadata(RTMPContext *rt, RTMPPacket *pkt)
+{
+int ret, old_flv_size, type;
+const uint8_t *next;
+uint8_t *p;
+uint32_t size;
+uint32_t ts, cts, pts = 0;
+
+old_flv_size = update_offset(rt, pkt-size);
+
+if ((ret = av_reallocp(rt-flv_data, rt-flv_size))  0)
+return ret;
+
+next = pkt-data;
+p= rt-flv_data + old_flv_size;
+
+/* copy data while rewriting timestamps */
+ts = pkt-timestamp;
+
+while (next - pkt-data  pkt-size - 11) {
+type = bytestream_get_byte(next);
+size = bytestream_get_be24(next);
+cts  = bytestream_get_be24(next);
+cts |= bytestream_get_byte(next)  24;
+if (!pts)
+pts = cts;
+ts += cts - pts;
+pts = cts;
+bytestream_put_byte(p, type);
+bytestream_put_be24(p, size);
+bytestream_put_be24(p, ts);
+bytestream_put_byte(p, ts  24);
+memcpy(p, next, size + 3 + 4);
+next += size + 3 + 4;
+p+= size + 3 + 4;
+}
+memcpy(p, next, 11);
+
+return 0;
+}
+
 /**
  * Interact with the server by receiving and sending RTMP packets until
  * there is some significant data (media data or expected status notification).
@@ -2199,10 +2240,6 @@ static int get_packet(URLContext *s, int for_header)
 {
 RTMPContext *rt = s-priv_data;
 int ret;
-uint8_t *p;
-const uint8_t *next;
-uint32_t size;
-uint32_t ts, cts, pts=0;
 
 if (rt-state == STATE_STOPPED)
 return AVERROR_EOF;
@@ -2269,30 +2306,7 @@ static int get_packet(URLContext *s, int for_header)
 ff_rtmp_packet_destroy(rpkt);
 return ret;
 } else if (rpkt.type == RTMP_PT_METADATA) {
-int err;
-// we got raw FLV data, make it available for FLV demuxer
-rt-flv_off  = 0;
-rt-flv_size = rpkt.size;
-if ((err = av_reallocp(rt-flv_data, rt-flv_size))  0)
-return err;
-/* rewrite timestamps */
-next = rpkt.data;
-ts = rpkt.timestamp;
-while (next - rpkt.data  rpkt.size - 11) {
-next++;
-size = bytestream_get_be24(next);
-p=next;
-cts = bytestream_get_be24(next);
-cts |= bytestream_get_byte(next)  24;
-if (pts==0)
-pts=cts;
-ts += cts - pts;
-pts = cts;
-bytestream_put_be24(p, ts);
-bytestream_put_byte(p, ts  24);
-next += size + 3 + 4;
-}
-memcpy(rt-flv_data, rpkt.data, rpkt.size);
+ret = handle_metadata(rt, rpkt);
 ff_rtmp_packet_destroy(rpkt);
 return 0;
 }
-- 
1.8.3.2

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


[libav-devel] [PATCH 3/5] rtmp: Refactor get_packet

2013-09-21 Thread Luca Barbato
---
 libavformat/rtmpproto.c | 116 ++--
 1 file changed, 54 insertions(+), 62 deletions(-)

diff --git a/libavformat/rtmpproto.c b/libavformat/rtmpproto.c
index a2dffd0..5a0bd7a 100644
--- a/libavformat/rtmpproto.c
+++ b/libavformat/rtmpproto.c
@@ -2061,65 +2061,78 @@ static int handle_invoke(URLContext *s, RTMPPacket *pkt)
 return ret;
 }
 
-static int handle_notify(URLContext *s, RTMPPacket *pkt) {
-RTMPContext *rt  = s-priv_data;
-const uint8_t *p = NULL;
-uint8_t commandbuffer[64];
-char statusmsg[128];
-int stringlen;
-GetByteContext gbc;
-PutByteContext pbc;
-uint32_t ts;
-int old_flv_size, err;
-const uint8_t *datatowrite;
-unsigned datatowritelength;
-
-p = pkt-data;
-bytestream2_init(gbc, p, pkt-size);
-if (ff_amf_read_string(gbc, commandbuffer, sizeof(commandbuffer),
-   stringlen))
-return AVERROR_INVALIDDATA;
-if (!strcmp(commandbuffer, @setDataFrame)) {
-datatowrite   = gbc.buffer;
-datatowritelength = bytestream2_get_bytes_left(gbc);
-if (ff_amf_read_string(gbc, statusmsg,
-   sizeof(statusmsg), stringlen))
-return AVERROR_INVALIDDATA;
-} else {
-datatowrite   = pkt-data;
-datatowritelength = pkt-size;
-}
-
-/* Provide ECMAArray to flv */
-ts = pkt-timestamp;
+static int update_offset(RTMPContext *rt, int size)
+{
+int old_flv_size;
 
 // generate packet header and put data into buffer for FLV demuxer
 if (rt-flv_off  rt-flv_size) {
 // There is old unread data in the buffer, thus append at the end
 old_flv_size  = rt-flv_size;
-rt-flv_size += datatowritelength + 15;
+rt-flv_size += size + 15;
 } else {
 // All data has been read, write the new data at the start of the 
buffer
 old_flv_size = 0;
-rt-flv_size = datatowritelength + 15;
+rt-flv_size = size + 15;
 rt-flv_off  = 0;
 }
 
-if ((err = av_reallocp(rt-flv_data, rt-flv_size))  0)
-return err;
+return old_flv_size;
+}
+
+static int append_flv_data(RTMPContext *rt, RTMPPacket *pkt, int skip)
+{
+int old_flv_size, ret;
+PutByteContext pbc;
+const uint8_t *data = pkt-data + skip;
+const int size  = pkt-size - skip;
+uint32_t ts = pkt-timestamp;
+
+old_flv_size = update_offset(rt, size);
+
+if ((ret = av_reallocp(rt-flv_data, rt-flv_size))  0)
+return ret;
 bytestream2_init_writer(pbc, rt-flv_data, rt-flv_size);
 bytestream2_skip_p(pbc, old_flv_size);
 bytestream2_put_byte(pbc, pkt-type);
-bytestream2_put_be24(pbc, datatowritelength);
+bytestream2_put_be24(pbc, size);
 bytestream2_put_be24(pbc, ts);
 bytestream2_put_byte(pbc, ts  24);
 bytestream2_put_be24(pbc, 0);
-bytestream2_put_buffer(pbc, datatowrite, datatowritelength);
+bytestream2_put_buffer(pbc, data, size);
 bytestream2_put_be32(pbc, 0);
 
 return 0;
 }
 
+static int handle_notify(URLContext *s, RTMPPacket *pkt)
+{
+RTMPContext *rt  = s-priv_data;
+uint8_t commandbuffer[64];
+char statusmsg[128];
+int stringlen, ret, skip = 0;
+GetByteContext gbc;
+
+bytestream2_init(gbc, pkt-data, pkt-size);
+if (ff_amf_read_string(gbc, commandbuffer, sizeof(commandbuffer),
+   stringlen))
+return AVERROR_INVALIDDATA;
+
+av_log(NULL, AV_LOG_ERROR, RTMP %s\n, commandbuffer);
+
+// Skip the @setDataFrame string and validate it is a notification
+if (!strcmp(commandbuffer, @setDataFrame)) {
+skip = gbc.buffer - pkt-data;
+ret = ff_amf_read_string(gbc, statusmsg,
+ sizeof(statusmsg), stringlen);
+if (ret  0)
+return AVERROR_INVALIDDATA;
+av_log(NULL, AV_LOG_ERROR, - %s\n, statusmsg);
+}
+
+return append_flv_data(rt, pkt, skip);
+}
+
 /**
  * Parse received packet and possibly perform some action depending on
  * the packet contents.
@@ -2247,35 +2260,14 @@ static int get_packet(URLContext *s, int for_header)
 ff_rtmp_packet_destroy(rpkt);
 continue;
 }
-if (rpkt.type == RTMP_PT_VIDEO || rpkt.type == RTMP_PT_AUDIO ||
-   (rpkt.type == RTMP_PT_NOTIFY 
-ff_amf_match_string(rpkt.data, rpkt.size, onMetaData))) {
-int err;
-ts = rpkt.timestamp;
-
-// generate packet header and put data into buffer for FLV demuxer
-rt-flv_off  = 0;
-rt-flv_size = rpkt.size + 15;
-if ((err = av_reallocp(rt-flv_data, rt-flv_size))  0)
-return err;
-p = rt-flv_data;
-bytestream_put_byte(p, rpkt.type);
-bytestream_put_be24(p, rpkt.size);
-bytestream_put_be24(p, ts);
-bytestream_put_byte(p, ts  24);
-

[libav-devel] RTMP refactoring/cleanup

2013-09-21 Thread Luca Barbato
[PATCH 1/5] rtmp: Support AMF_DATA_TYPE_MIXEDARRAY
[PATCH 2/5] flv: Make onTextData parsing robust
Those two should be fine, hopefully.

[PATCH 3/5] rtmp: Refactor get_packet
Unchanged

[PATCH 4/5] rtmp: Rewrite embedded flv handling
Following Josh suggestions

[PATCH 5/5] rtmp: Replace a magic number with a macro
While at it some 11 got removed =P


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


[libav-devel] [PATCH 1/5] rtmp: Support AMF_DATA_TYPE_MIXEDARRAY

2013-09-21 Thread Luca Barbato
And fix the AMF_DATA_TYPE_ARRAY parsing while at it.

A MIXEDARRAY type, as the ARRAY, store the number of elements in
an uint32 before the list. The ARRAY is strict and does not have
an OBJECT terminator, MIXEDARRAY behaves like an OBJECT type and
a different than stated number of element can be present.
---
 libavformat/rtmppkt.c | 65 +++
 1 file changed, 40 insertions(+), 25 deletions(-)

diff --git a/libavformat/rtmppkt.c b/libavformat/rtmppkt.c
index 922ca3e..defe81e 100644
--- a/libavformat/rtmppkt.c
+++ b/libavformat/rtmppkt.c
@@ -370,28 +370,35 @@ void ff_rtmp_packet_destroy(RTMPPacket *pkt)
 int ff_amf_tag_size(const uint8_t *data, const uint8_t *data_end)
 {
 const uint8_t *base = data;
+AMFDataType type;
+unsigned nb   = -1;
+int parse_key = 1;
 
 if (data = data_end)
 return -1;
-switch (*data++) {
+switch ((type = *data++)) {
 case AMF_DATA_TYPE_NUMBER:  return 9;
 case AMF_DATA_TYPE_BOOL:return 2;
 case AMF_DATA_TYPE_STRING:  return 3 + AV_RB16(data);
 case AMF_DATA_TYPE_LONG_STRING: return 5 + AV_RB32(data);
 case AMF_DATA_TYPE_NULL:return 1;
 case AMF_DATA_TYPE_ARRAY:
-data += 4;
+parse_key = 0;
+case AMF_DATA_TYPE_MIXEDARRAY:
+nb = bytestream_get_be32(data);
 case AMF_DATA_TYPE_OBJECT:
-for (;;) {
-int size = bytestream_get_be16(data);
+while (nb--  0 || type != AMF_DATA_TYPE_ARRAY) {
 int t;
-if (!size) {
-data++;
-break;
+if (parse_key) {
+int size = bytestream_get_be16(data);
+if (!size) {
+data++;
+break;
+}
+if (size  0 || size = data_end - data)
+return -1;
+data += size;
 }
-if (size  0 || size = data_end - data)
-return -1;
-data += size;
 t = ff_amf_tag_size(data, data_end);
 if (t  0 || t = data_end - data)
 return -1;
@@ -474,12 +481,14 @@ static const char* rtmp_packet_type(int type)
 static void amf_tag_contents(void *ctx, const uint8_t *data,
  const uint8_t *data_end)
 {
-unsigned int size;
+unsigned int size, nb = -1;
 char buf[1024];
+AMFDataType type;
+int parse_key = 1;
 
 if (data = data_end)
 return;
-switch (*data++) {
+switch ((type = *data++)) {
 case AMF_DATA_TYPE_NUMBER:
 av_log(ctx, AV_LOG_DEBUG,  number %g\n, 
av_int2double(AV_RB64(data)));
 return;
@@ -488,7 +497,7 @@ static void amf_tag_contents(void *ctx, const uint8_t *data,
 return;
 case AMF_DATA_TYPE_STRING:
 case AMF_DATA_TYPE_LONG_STRING:
-if (data[-1] == AMF_DATA_TYPE_STRING) {
+if (type == AMF_DATA_TYPE_STRING) {
 size = bytestream_get_be16(data);
 } else {
 size = bytestream_get_be32(data);
@@ -502,22 +511,28 @@ static void amf_tag_contents(void *ctx, const uint8_t 
*data,
 av_log(ctx, AV_LOG_DEBUG,  NULL\n);
 return;
 case AMF_DATA_TYPE_ARRAY:
-data += 4;
+parse_key = 0;
+case AMF_DATA_TYPE_MIXEDARRAY:
+nb = bytestream_get_be32(data);
 case AMF_DATA_TYPE_OBJECT:
 av_log(ctx, AV_LOG_DEBUG,  {\n);
-for (;;) {
+while (nb--  0 || type != AMF_DATA_TYPE_ARRAY) {
 int t;
-size = bytestream_get_be16(data);
-av_strlcpy(buf, data, FFMIN(sizeof(buf), size + 1));
-if (!size) {
-av_log(ctx, AV_LOG_DEBUG,  }\n);
-data++;
-break;
+if (parse_key) {
+size = bytestream_get_be16(data);
+size = FFMIN(size, sizeof(buf) - 1);
+if (!size) {
+av_log(ctx, AV_LOG_DEBUG,  }\n);
+data++;
+break;
+}
+memcpy(buf, data, size);
+buf[size] = 0;
+if (size = data_end - data)
+return;
+data += size;
+av_log(ctx, AV_LOG_DEBUG,   %s: , buf);
 }
-if (size = data_end - data)
-return;
-data += size;
-av_log(ctx, AV_LOG_DEBUG,   %s: , buf);
 amf_tag_contents(ctx, data, data_end);
 t = ff_amf_tag_size(data, data_end);
 if (t  0 || t = data_end - data)
-- 
1.8.3.2

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


[libav-devel] [PATCH 2/5] flv: Make onTextData parsing robust

2013-09-21 Thread Luca Barbato
Certain streaming servers do not preserve the order of the fields.
---
 libavformat/flvdec.c | 88 
 1 file changed, 69 insertions(+), 19 deletions(-)

diff --git a/libavformat/flvdec.c b/libavformat/flvdec.c
index b8feeaf..9f4a391 100644
--- a/libavformat/flvdec.c
+++ b/libavformat/flvdec.c
@@ -634,35 +634,84 @@ static void clear_index_entries(AVFormatContext *s, 
int64_t pos)
 }
 }
 
+static int amf_skip_tag(AVIOContext *pb, AMFDataType type)
+{
+int nb = -1, ret, parse_name = 1;
+
+switch (type) {
+case AMF_DATA_TYPE_NUMBER:
+avio_skip(pb, 8);
+break;
+case AMF_DATA_TYPE_BOOL:
+avio_skip(pb, 1);
+break;
+case AMF_DATA_TYPE_STRING:
+avio_skip(pb, avio_rb16(pb));
+break;
+case AMF_DATA_TYPE_ARRAY:
+parse_name = 0;
+case AMF_DATA_TYPE_MIXEDARRAY:
+nb = avio_rb32(pb);
+case AMF_DATA_TYPE_OBJECT:
+while(!pb-eof_reached  (nb  0 || type != AMF_DATA_TYPE_ARRAY)) {
+if (parse_name) {
+int size = avio_rb16(pb);
+if (!size) {
+avio_skip(pb, 1);
+break;
+}
+avio_skip(pb, size);
+}
+if ((ret = amf_skip_tag(pb, avio_r8(pb)))  0)
+return ret;
+}
+break;
+case AMF_DATA_TYPE_NULL:
+case AMF_DATA_TYPE_OBJECT_END:
+break;
+default:
+return AVERROR_INVALIDDATA;
+}
+return 0;
+}
+
 static int flv_data_packet(AVFormatContext *s, AVPacket *pkt,
int64_t dts, int64_t next)
 {
 AVIOContext *pb = s-pb;
 AVStream *st= NULL;
-AMFDataType type;
 char buf[20];
-int ret, i, length;
+int ret = AVERROR_INVALIDDATA;
+int i, length = -1;
 
-type = avio_r8(pb);
-if (type == AMF_DATA_TYPE_MIXEDARRAY)
+switch (avio_r8(pb)) {
+case AMF_DATA_TYPE_MIXEDARRAY:
 avio_seek(pb, 4, SEEK_CUR);
-else if (type != AMF_DATA_TYPE_OBJECT)
-return AVERROR_INVALIDDATA;
-
-amf_get_string(pb, buf, sizeof(buf));
-if (strcmp(buf, type) || avio_r8(pb) != AMF_DATA_TYPE_STRING)
-return AVERROR_INVALIDDATA;
+case AMF_DATA_TYPE_OBJECT:
+break;
+default:
+goto skip;
+}
 
-amf_get_string(pb, buf, sizeof(buf));
-// FIXME parse it as codec_id
-amf_get_string(pb, buf, sizeof(buf));
-if (strcmp(buf, text) || avio_r8(pb) != AMF_DATA_TYPE_STRING)
-return AVERROR_INVALIDDATA;
+while ((ret = amf_get_string(pb, buf, sizeof(buf)))  0) {
+AMFDataType type = avio_r8(pb);
+if (type == AMF_DATA_TYPE_STRING  !strcmp(buf, text)) {
+length = avio_rb16(pb);
+ret= av_get_packet(pb, pkt, length);
+if (ret  0)
+goto skip;
+else
+break;
+} else {
+if ((ret = amf_skip_tag(pb, type))  0)
+goto skip;
+}
+}
 
-length = avio_rb16(pb);
-ret= av_get_packet(s-pb, pkt, length);
-if (ret  0)
-return AVERROR(EIO);
+if (length  0) {
+ret = AVERROR_INVALIDDATA;
+goto skip;
+}
 
 for (i = 0; i  s-nb_streams; i++) {
 st = s-streams[i];
@@ -684,6 +733,7 @@ static int flv_data_packet(AVFormatContext *s, AVPacket 
*pkt,
 pkt-stream_index = st-index;
 pkt-flags   |= AV_PKT_FLAG_KEY;
 
+skip:
 avio_seek(s-pb, next + 4, SEEK_SET);
 
 return ret;
-- 
1.8.3.2

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


[libav-devel] [PATCH 5/5] rtmp: Replace a magic number with a macro

2013-09-21 Thread Luca Barbato
11 is the RTMP header size.
---
 libavformat/rtmpproto.c | 15 ---
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/libavformat/rtmpproto.c b/libavformat/rtmpproto.c
index deaef23..eaa45bc 100644
--- a/libavformat/rtmpproto.c
+++ b/libavformat/rtmpproto.c
@@ -53,6 +53,7 @@
 #define TCURL_MAX_LENGTH 512
 #define FLASHVER_MAX_LENGTH 64
 #define RTMP_PKTDATA_DEFAULT_SIZE 4096
+#define RTMP_HEADER 11
 
 /** RTMP protocol handler state */
 typedef enum {
@@ -95,7 +96,7 @@ typedef struct RTMPContext {
 uint32_t  bytes_read; /// number of bytes read from 
server
 uint32_t  last_bytes_read;/// number of bytes read last 
reported to server
 int   skip_bytes; /// number of bytes to skip 
from the input FLV stream in the next write call
-uint8_t   flv_header[11]; /// partial incoming flv packet 
header
+uint8_t   flv_header[RTMP_HEADER];/// partial incoming flv packet 
header
 int   flv_header_bytes;   /// number of initialized bytes 
in flv_header
 int   nb_invokes; /// keeps track of invoke 
messages
 char* tcurl;  /// url of the target stream
@@ -2001,7 +2002,7 @@ static int handle_invoke_status(URLContext *s, RTMPPacket 
*pkt)
 {
 RTMPContext *rt = s-priv_data;
 const uint8_t *data_end = pkt-data + pkt-size;
-const uint8_t *ptr = pkt-data + 11;
+const uint8_t *ptr = pkt-data + RTMP_HEADER;
 uint8_t tmpstr[256];
 int i, t;
 
@@ -2203,7 +2204,7 @@ static int handle_metadata(RTMPContext *rt, RTMPPacket 
*pkt)
 /* copy data while rewriting timestamps */
 ts = pkt-timestamp;
 
-while (next - pkt-data  pkt-size - 11) {
+while (next - pkt-data  pkt-size - RTMP_HEADER) {
 type = bytestream_get_byte(next);
 size = bytestream_get_be24(next);
 cts  = bytestream_get_be24(next);
@@ -2220,7 +2221,7 @@ static int handle_metadata(RTMPContext *rt, RTMPPacket 
*pkt)
 next += size + 3 + 4;
 p+= size + 3 + 4;
 }
-memcpy(p, next, 11);
+memcpy(p, next, RTMP_HEADER);
 
 return 0;
 }
@@ -2647,14 +2648,14 @@ static int rtmp_write(URLContext *s, const uint8_t 
*buf, int size)
 continue;
 }
 
-if (rt-flv_header_bytes  11) {
+if (rt-flv_header_bytes  RTMP_HEADER) {
 const uint8_t *header = rt-flv_header;
-int copy = FFMIN(11 - rt-flv_header_bytes, size_temp);
+int copy = FFMIN(RTMP_HEADER - rt-flv_header_bytes, size_temp);
 int channel = RTMP_AUDIO_CHANNEL;
 bytestream_get_buffer(buf_temp, rt-flv_header + 
rt-flv_header_bytes, copy);
 rt-flv_header_bytes += copy;
 size_temp-= copy;
-if (rt-flv_header_bytes  11)
+if (rt-flv_header_bytes  RTMP_HEADER)
 break;
 
 pkttype = bytestream_get_byte(header);
-- 
1.8.3.2

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


Re: [libav-devel] RTMP refactoring/cleanup

2013-09-21 Thread Josh Allmann
On 21 September 2013 12:45, Luca Barbato lu_z...@gentoo.org wrote:
 [PATCH 1/5] rtmp: Support AMF_DATA_TYPE_MIXEDARRAY
 [PATCH 2/5] flv: Make onTextData parsing robust
 Those two should be fine, hopefully.

 [PATCH 3/5] rtmp: Refactor get_packet
 Unchanged

 [PATCH 4/5] rtmp: Rewrite embedded flv handling
 Following Josh suggestions

 [PATCH 5/5] rtmp: Replace a magic number with a macro
 While at it some 11 got removed =P


Other than the stray av_logs still in get_packet, these look good to me.

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


[libav-devel] [PATCH 1/7] wnv1: Make sure the input packet is large enough

2013-09-21 Thread Martin Storsjö
Reported-by: Mateusz j00ru Jurczyk and Gynvael Coldwind
CC: libav-sta...@libav.org
---
 libavcodec/wnv1.c |5 +
 1 file changed, 5 insertions(+)

diff --git a/libavcodec/wnv1.c b/libavcodec/wnv1.c
index 418c5f7..13a875e 100644
--- a/libavcodec/wnv1.c
+++ b/libavcodec/wnv1.c
@@ -70,6 +70,11 @@ static int decode_frame(AVCodecContext *avctx,
 int prev_y = 0, prev_u = 0, prev_v = 0;
 uint8_t *rbuf;
 
+if (buf_size  8) {
+av_log(avctx, AV_LOG_ERROR, Packet is too short\n);
+return AVERROR_INVALIDDATA;
+}
+
 rbuf = av_malloc(buf_size + FF_INPUT_BUFFER_PADDING_SIZE);
 if (!rbuf) {
 av_log(avctx, AV_LOG_ERROR, Cannot allocate temporary buffer\n);
-- 
1.7.9.5

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


[libav-devel] [PATCH 6/7] lavf: Avoid setting avg_frame_rate if delta_dts is negative

2013-09-21 Thread Martin Storsjö
This avoids setting avg_frame_rate to invalid (negative)
values.

Reported-by: Mateusz j00ru Jurczyk and Gynvael Coldwind
CC: libav-sta...@libav.org
---
 libavformat/utils.c |3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/libavformat/utils.c b/libavformat/utils.c
index 22f6d01..0700c5d 100644
--- a/libavformat/utils.c
+++ b/libavformat/utils.c
@@ -2373,7 +2373,8 @@ int avformat_find_stream_info(AVFormatContext *ic, 
AVDictionary **options)
 double best_error = 0.01;
 
 if (delta_dts = INT64_MAX / st-time_base.num ||
-delta_packets = INT64_MAX / st-time_base.den)
+delta_packets = INT64_MAX / st-time_base.den ||
+delta_dts  0)
 continue;
 av_reduce(st-avg_frame_rate.num, st-avg_frame_rate.den,
   delta_packets*(int64_t)st-time_base.den,
-- 
1.7.9.5

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


[libav-devel] [PATCH 2/7] vc1dec: Fix leaks in ff_vc1_decode_init_alloc_tables on errors

2013-09-21 Thread Martin Storsjö
Reported-by: Mateusz j00ru Jurczyk and Gynvael Coldwind
CC: libav-sta...@libav.org
---
 libavcodec/vc1dec.c |   15 +--
 1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/libavcodec/vc1dec.c b/libavcodec/vc1dec.c
index 0feff21..35a0fe7 100644
--- a/libavcodec/vc1dec.c
+++ b/libavcodec/vc1dec.c
@@ -5525,8 +5525,19 @@ av_cold int ff_vc1_decode_init_alloc_tables(VC1Context 
*v)
 
 if (!v-mv_type_mb_plane || !v-direct_mb_plane || !v-acpred_plane || 
!v-over_flags_plane ||
 !v-block || !v-cbp_base || !v-ttblk_base || !v-is_intra_base || 
!v-luma_mv_base ||
-!v-mb_type_base)
-return -1;
+!v-mb_type_base) {
+av_freep(v-mv_type_mb_plane);
+av_freep(v-direct_mb_plane);
+av_freep(v-acpred_plane);
+av_freep(v-over_flags_plane);
+av_freep(v-block);
+av_freep(v-cbp_base);
+av_freep(v-ttblk_base);
+av_freep(v-is_intra_base);
+av_freep(v-luma_mv_base);
+av_freep(v-mb_type_base);
+return AVERROR(ENOMEM);
+}
 
 return 0;
 }
-- 
1.7.9.5

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


[libav-devel] [PATCH 3/7] vc1dec: Undo mpegvideo initialization if untable to allocate tables

2013-09-21 Thread Martin Storsjö
Previously, s-context_initialized was left set to 1
if ff_vc1_decode_init_alloc_tables failed, skipping the
initialization completely on the next decode call.

Reported-by: Mateusz j00ru Jurczyk and Gynvael Coldwind
CC: libav-sta...@libav.org
---
 libavcodec/vc1dec.c |6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/libavcodec/vc1dec.c b/libavcodec/vc1dec.c
index 35a0fe7..d0566a3 100644
--- a/libavcodec/vc1dec.c
+++ b/libavcodec/vc1dec.c
@@ -5877,8 +5877,12 @@ static int vc1_decode_frame(AVCodecContext *avctx, void 
*data,
 }
 
 if (!s-context_initialized) {
-if (ff_msmpeg4_decode_init(avctx)  0 || 
ff_vc1_decode_init_alloc_tables(v)  0)
+if (ff_msmpeg4_decode_init(avctx)  0)
 goto err;
+if (ff_vc1_decode_init_alloc_tables(v)  0) {
+ff_MPV_common_end(s);
+goto err;
+}
 
 s-low_delay = !avctx-has_b_frames || v-res_sprite;
 
-- 
1.7.9.5

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


[libav-devel] [PATCH 4/7] vc1dec: Make sure last_picture is initialized in vc1_decode_skip_blocks

2013-09-21 Thread Martin Storsjö
Reported-by: Mateusz j00ru Jurczyk and Gynvael Coldwind
CC: libav-sta...@libav.org
---
 libavcodec/vc1dec.c |3 +++
 1 file changed, 3 insertions(+)

diff --git a/libavcodec/vc1dec.c b/libavcodec/vc1dec.c
index d0566a3..4fcc818 100644
--- a/libavcodec/vc1dec.c
+++ b/libavcodec/vc1dec.c
@@ -5143,6 +5143,9 @@ static void vc1_decode_skip_blocks(VC1Context *v)
 {
 MpegEncContext *s = v-s;
 
+if (!v-s.last_picture.f.data[0])
+return;
+
 ff_er_add_slice(s-er, 0, s-start_mb_y, s-mb_width - 1, s-end_mb_y - 
1, ER_MB_END);
 s-first_slice_line = 1;
 for (s-mb_y = s-start_mb_y; s-mb_y  s-end_mb_y; s-mb_y++) {
-- 
1.7.9.5

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


[libav-devel] [PATCH 5/7] vc1dec: Don't decode slices when the latest slice header failed to decode

2013-09-21 Thread Martin Storsjö
From: Michael Niedermayer michae...@gmx.at

Reported-by: Mateusz j00ru Jurczyk and Gynvael Coldwind
CC: libav-sta...@libav.org
---
 libavcodec/vc1dec.c |8 ++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/libavcodec/vc1dec.c b/libavcodec/vc1dec.c
index 4fcc818..602b155 100644
--- a/libavcodec/vc1dec.c
+++ b/libavcodec/vc1dec.c
@@ -5972,6 +5972,8 @@ static int vc1_decode_frame(AVCodecContext *avctx, void 
*data,
 if (avctx-hwaccel-end_frame(avctx)  0)
 goto err;
 } else {
+int header_ret = 0;
+
 ff_mpeg_er_frame_start(s);
 
 v-bits = buf_size * 8;
@@ -6009,18 +6011,20 @@ static int vc1_decode_frame(AVCodecContext *avctx, void 
*data,
 if (i) {
 v-pic_header_flag = 0;
 if (v-field_mode  i == n_slices1 + 2) {
-if (ff_vc1_parse_frame_header_adv(v, s-gb)  0) {
+if ((header_ret = ff_vc1_parse_frame_header_adv(v, 
s-gb))  0) {
 av_log(v-s.avctx, AV_LOG_ERROR, Field header 
damaged\n);
 continue;
 }
 } else if (get_bits1(s-gb)) {
 v-pic_header_flag = 1;
-if (ff_vc1_parse_frame_header_adv(v, s-gb)  0) {
+if ((header_ret = ff_vc1_parse_frame_header_adv(v, 
s-gb))  0) {
 av_log(v-s.avctx, AV_LOG_ERROR, Slice header 
damaged\n);
 continue;
 }
 }
 }
+if (header_ret  0)
+continue;
 s-start_mb_y = (i == 0) ? 0 : FFMAX(0, slices[i-1].mby_start % 
mb_height);
 if (!v-field_mode || v-second_field)
 s-end_mb_y = (i == n_slices ) ? mb_height : 
FFMIN(mb_height, slices[i].mby_start % mb_height);
-- 
1.7.9.5

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


[libav-devel] [PATCH 7/7] electronicarts: Check packet sizes before reading

2013-09-21 Thread Martin Storsjö
Reported-by: Mateusz j00ru Jurczyk and Gynvael Coldwind
CC: libav-sta...@libav.org
---
 libavformat/electronicarts.c |   12 +---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/libavformat/electronicarts.c b/libavformat/electronicarts.c
index e764bd9..b0e0674 100644
--- a/libavformat/electronicarts.c
+++ b/libavformat/electronicarts.c
@@ -555,10 +555,16 @@ static int ea_read_packet(AVFormatContext *s, AVPacket 
*pkt)
 case AV_CODEC_ID_ADPCM_EA_R1:
 case AV_CODEC_ID_ADPCM_EA_R2:
 case AV_CODEC_ID_ADPCM_IMA_EA_EACS:
-pkt-duration = AV_RL32(pkt-data);
-break;
 case AV_CODEC_ID_ADPCM_EA_R3:
-pkt-duration = AV_RB32(pkt-data);
+if (pkt-size  4) {
+av_log(s, AV_LOG_ERROR, Packet is too short\n);
+av_free_packet(pkt);
+return AVERROR_INVALIDDATA;
+}
+if (ea-audio_codec == AV_CODEC_ID_ADPCM_EA_R3)
+pkt-duration = AV_RB32(pkt-data);
+else
+pkt-duration = AV_RL32(pkt-data);
 break;
 case AV_CODEC_ID_ADPCM_IMA_EA_SEAD:
 pkt-duration = ret * 2 / ea-num_channels;
-- 
1.7.9.5

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


[libav-devel] [PATCH] tls: Don't abort on non-fatal TLS alerts with gnutls

2013-09-21 Thread Martin Storsjö
---
 libavformat/tls.c |9 -
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/libavformat/tls.c b/libavformat/tls.c
index fecf096..7fa6fc2 100644
--- a/libavformat/tls.c
+++ b/libavformat/tls.c
@@ -72,7 +72,14 @@ static int do_tls_poll(URLContext *h, int ret)
 TLSContext *c = h-priv_data;
 struct pollfd p = { c-fd, 0, 0 };
 #if CONFIG_GNUTLS
-if (ret != GNUTLS_E_AGAIN  ret != GNUTLS_E_INTERRUPTED) {
+switch (ret) {
+case GNUTLS_E_AGAIN:
+case GNUTLS_E_INTERRUPTED:
+break;
+case GNUTLS_E_WARNING_ALERT_RECEIVED:
+av_log(h, AV_LOG_WARNING, %s\n, gnutls_strerror(ret));
+break;
+default:
 av_log(h, AV_LOG_ERROR, %s\n, gnutls_strerror(ret));
 return AVERROR(EIO);
 }
-- 
1.7.9.4

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


[libav-devel] [PATCH 1/3] movenc: Set mov-mode earlier in mov_write_header

2013-09-21 Thread Martin Storsjö
This allows simplifying some early checks that depend on the
muxer mode.
---
 libavformat/movenc.c |   37 +++--
 1 file changed, 19 insertions(+), 18 deletions(-)

diff --git a/libavformat/movenc.c b/libavformat/movenc.c
index dbff369..dd0a31f 100644
--- a/libavformat/movenc.c
+++ b/libavformat/movenc.c
@@ -3139,10 +3139,22 @@ static int mov_write_header(AVFormatContext *s)
 AVDictionaryEntry *t;
 int i, hint_track = 0;
 
+/* Default mode == MP4 */
+mov-mode = MODE_MP4;
+
+if (s-oformat != NULL) {
+if (!strcmp(3gp, s-oformat-name)) mov-mode = MODE_3GP;
+else if (!strcmp(3g2, s-oformat-name)) mov-mode = 
MODE_3GP|MODE_3G2;
+else if (!strcmp(mov, s-oformat-name)) mov-mode = MODE_MOV;
+else if (!strcmp(psp, s-oformat-name)) mov-mode = MODE_PSP;
+else if (!strcmp(ipod,s-oformat-name)) mov-mode = MODE_IPOD;
+else if (!strcmp(ismv,s-oformat-name)) mov-mode = MODE_ISM;
+}
+
 /* Set the FRAGMENT flag if any of the fragmentation methods are
  * enabled. */
 if (mov-max_fragment_duration || mov-max_fragment_size ||
-(s-oformat  !strcmp(s-oformat-name, ismv)) ||
+mov-mode == MODE_ISM ||
 mov-flags  (FF_MOV_FLAG_EMPTY_MOOV |
   FF_MOV_FLAG_FRAG_KEYFRAME |
   FF_MOV_FLAG_FRAG_CUSTOM))
@@ -3166,25 +3178,14 @@ static int mov_write_header(AVFormatContext *s)
 return -1;
 }
 
-/* Default mode == MP4 */
-mov-mode = MODE_MP4;
-
-if (s-oformat != NULL) {
-if (!strcmp(3gp, s-oformat-name)) mov-mode = MODE_3GP;
-else if (!strcmp(3g2, s-oformat-name)) mov-mode = 
MODE_3GP|MODE_3G2;
-else if (!strcmp(mov, s-oformat-name)) mov-mode = MODE_MOV;
-else if (!strcmp(psp, s-oformat-name)) mov-mode = MODE_PSP;
-else if (!strcmp(ipod,s-oformat-name)) mov-mode = MODE_IPOD;
-else if (!strcmp(ismv,s-oformat-name)) mov-mode = MODE_ISM;
 
-mov_write_ftyp_tag(pb,s);
-if (mov-mode == MODE_PSP) {
-if (s-nb_streams != 2) {
-av_log(s, AV_LOG_ERROR, PSP mode need one video and one audio 
stream\n);
-return -1;
-}
-mov_write_uuidprof_tag(pb, s);
+mov_write_ftyp_tag(pb,s);
+if (mov-mode == MODE_PSP) {
+if (s-nb_streams != 2) {
+av_log(s, AV_LOG_ERROR, PSP mode need one video and one audio 
stream\n);
+return -1;
 }
+mov_write_uuidprof_tag(pb, s);
 }
 
 mov-nb_streams = s-nb_streams;
-- 
1.7.9.4

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


[libav-devel] [PATCH 3/3] movenc: Use keyframes as default fragmentation point in ismv

2013-09-21 Thread Martin Storsjö
Fragmenting blindly to a certain duration isn't a good choice
if one should be able to switch between different qualities,
therefore default to keyframes instead.
---
 libavformat/movenc.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libavformat/movenc.c b/libavformat/movenc.c
index 16107b1..f4bd990 100644
--- a/libavformat/movenc.c
+++ b/libavformat/movenc.c
@@ -3300,7 +3300,7 @@ static int mov_write_header(AVFormatContext *s)
 if (!(mov-flags  (FF_MOV_FLAG_FRAG_KEYFRAME |
 FF_MOV_FLAG_FRAG_CUSTOM)) 
 !mov-max_fragment_duration  !mov-max_fragment_size)
-mov-max_fragment_duration = 500;
+mov-flags |= FF_MOV_FLAG_FRAG_KEYFRAME;
 }
 
 if (!(mov-flags  FF_MOV_FLAG_FRAGMENT)) {
-- 
1.7.9.4

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


[libav-devel] [PATCH 2/3] movenc: Set all implicit flags immediately in mov_write_header

2013-09-21 Thread Martin Storsjö
This makes sure other sanity checks for conflicting options
can work properly, e.g. for the conflict between the faststart
flag when using the ismv mode.
---
 libavformat/movenc.c |7 +--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/libavformat/movenc.c b/libavformat/movenc.c
index dd0a31f..16107b1 100644
--- a/libavformat/movenc.c
+++ b/libavformat/movenc.c
@@ -3154,12 +3154,16 @@ static int mov_write_header(AVFormatContext *s)
 /* Set the FRAGMENT flag if any of the fragmentation methods are
  * enabled. */
 if (mov-max_fragment_duration || mov-max_fragment_size ||
-mov-mode == MODE_ISM ||
 mov-flags  (FF_MOV_FLAG_EMPTY_MOOV |
   FF_MOV_FLAG_FRAG_KEYFRAME |
   FF_MOV_FLAG_FRAG_CUSTOM))
 mov-flags |= FF_MOV_FLAG_FRAGMENT;
 
+/* Set other implicit flags immediately */
+if (mov-mode == MODE_ISM)
+mov-flags |= FF_MOV_FLAG_EMPTY_MOOV | FF_MOV_FLAG_SEPARATE_MOOF |
+  FF_MOV_FLAG_FRAGMENT;
+
 /* faststart: moov at the beginning of the file, if supported */
 if (mov-flags  FF_MOV_FLAG_FASTSTART) {
 if ((mov-flags  FF_MOV_FLAG_FRAGMENT) ||
@@ -3297,7 +3301,6 @@ static int mov_write_header(AVFormatContext *s)
 FF_MOV_FLAG_FRAG_CUSTOM)) 
 !mov-max_fragment_duration  !mov-max_fragment_size)
 mov-max_fragment_duration = 500;
-mov-flags |= FF_MOV_FLAG_EMPTY_MOOV | FF_MOV_FLAG_SEPARATE_MOOF;
 }
 
 if (!(mov-flags  FF_MOV_FLAG_FRAGMENT)) {
-- 
1.7.9.4

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


Re: [libav-devel] [PATCH 7/7] electronicarts: Check packet sizes before reading

2013-09-21 Thread Luca Barbato
On 21/09/13 23:55, Martin Storsjö wrote:
 Reported-by: Mateusz j00ru Jurczyk and Gynvael Coldwind
 CC: libav-sta...@libav.org
 ---
  libavformat/electronicarts.c |   12 +---
  1 file changed, 9 insertions(+), 3 deletions(-)
 

Ok.

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

Re: [libav-devel] [PATCH 6/7] lavf: Avoid setting avg_frame_rate if delta_dts is negative

2013-09-21 Thread Luca Barbato
On 21/09/13 23:55, Martin Storsjö wrote:
 This avoids setting avg_frame_rate to invalid (negative)
 values.
 

Ok.

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

Re: [libav-devel] [PATCH 4/7] vc1dec: Make sure last_picture is initialized in vc1_decode_skip_blocks

2013-09-21 Thread Luca Barbato
On 21/09/13 23:55, Martin Storsjö wrote:
 Reported-by: Mateusz j00ru Jurczyk and Gynvael Coldwind
 CC: libav-sta...@libav.org
 ---
  libavcodec/vc1dec.c |3 +++
  1 file changed, 3 insertions(+)
 

Ok.

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

Re: [libav-devel] [PATCH 5/7] vc1dec: Don't decode slices when the latest slice header failed to decode

2013-09-21 Thread Luca Barbato
On 21/09/13 23:55, Martin Storsjö wrote:
 From: Michael Niedermayer michae...@gmx.at
 
 Reported-by: Mateusz j00ru Jurczyk and Gynvael Coldwind
 CC: libav-sta...@libav.org
 ---
  libavcodec/vc1dec.c |8 ++--
  1 file changed, 6 insertions(+), 2 deletions(-)
 

Might not hurt, note if possible we might want to return early if the
user wants explode-level checks.

lu

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

Re: [libav-devel] [PATCH 2/7] vc1dec: Fix leaks in ff_vc1_decode_init_alloc_tables on errors

2013-09-21 Thread Luca Barbato
On 21/09/13 23:55, Martin Storsjö wrote:
 Reported-by: Mateusz j00ru Jurczyk and Gynvael Coldwind
 CC: libav-sta...@libav.org
 ---
  libavcodec/vc1dec.c |   15 +--
  1 file changed, 13 insertions(+), 2 deletions(-)
 

Ok.

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

Re: [libav-devel] [PATCH 3/7] vc1dec: Undo mpegvideo initialization if untable to allocate tables

2013-09-21 Thread Luca Barbato
On 21/09/13 23:55, Martin Storsjö wrote:
 Previously, s-context_initialized was left set to 1
 if ff_vc1_decode_init_alloc_tables failed, skipping the
 initialization completely on the next decode call.
 
 Reported-by: Mateusz j00ru Jurczyk and Gynvael Coldwind
 CC: libav-sta...@libav.org
 ---
  libavcodec/vc1dec.c |6 +-
  1 file changed, 5 insertions(+), 1 deletion(-)
 

Ok.

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

Re: [libav-devel] [PATCH 1/7] wnv1: Make sure the input packet is large enough

2013-09-21 Thread Luca Barbato
On 21/09/13 23:55, Martin Storsjö wrote:
 Reported-by: Mateusz j00ru Jurczyk and Gynvael Coldwind
 CC: libav-sta...@libav.org
 ---
  libavcodec/wnv1.c |5 +
  1 file changed, 5 insertions(+)
 

8 is a little magic but guessable, ok if you don't feel going the extra
mile.

lu

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

Re: [libav-devel] [PATCH 1/3] movenc: Set mov-mode earlier in mov_write_header

2013-09-21 Thread Luca Barbato
On 22/09/13 00:35, Martin Storsjö wrote:
 This allows simplifying some early checks that depend on the
 muxer mode.
 ---
  libavformat/movenc.c |   37 +++--
  1 file changed, 19 insertions(+), 18 deletions(-)
 
 diff --git a/libavformat/movenc.c b/libavformat/movenc.c
 index dbff369..dd0a31f 100644
 --- a/libavformat/movenc.c
 +++ b/libavformat/movenc.c
 @@ -3139,10 +3139,22 @@ static int mov_write_header(AVFormatContext *s)
  AVDictionaryEntry *t;
  int i, hint_track = 0;
  
 +/* Default mode == MP4 */
 +mov-mode = MODE_MP4;
 +
 +if (s-oformat != NULL) {
 +if (!strcmp(3gp, s-oformat-name)) mov-mode = MODE_3GP;
 +else if (!strcmp(3g2, s-oformat-name)) mov-mode = 
 MODE_3GP|MODE_3G2;
 +else if (!strcmp(mov, s-oformat-name)) mov-mode = MODE_MOV;
 +else if (!strcmp(psp, s-oformat-name)) mov-mode = MODE_PSP;
 +else if (!strcmp(ipod,s-oformat-name)) mov-mode = MODE_IPOD;
 +else if (!strcmp(ismv,s-oformat-name)) mov-mode = MODE_ISM;
 +}
 +
  /* Set the FRAGMENT flag if any of the fragmentation methods are
   * enabled. */
  if (mov-max_fragment_duration || mov-max_fragment_size ||
 -(s-oformat  !strcmp(s-oformat-name, ismv)) ||
 +mov-mode == MODE_ISM ||
  mov-flags  (FF_MOV_FLAG_EMPTY_MOOV |
FF_MOV_FLAG_FRAG_KEYFRAME |
FF_MOV_FLAG_FRAG_CUSTOM))
 @@ -3166,25 +3178,14 @@ static int mov_write_header(AVFormatContext *s)
  return -1;
  }
  
 -/* Default mode == MP4 */
 -mov-mode = MODE_MP4;
 -
 -if (s-oformat != NULL) {
 -if (!strcmp(3gp, s-oformat-name)) mov-mode = MODE_3GP;
 -else if (!strcmp(3g2, s-oformat-name)) mov-mode = 
 MODE_3GP|MODE_3G2;
 -else if (!strcmp(mov, s-oformat-name)) mov-mode = MODE_MOV;
 -else if (!strcmp(psp, s-oformat-name)) mov-mode = MODE_PSP;
 -else if (!strcmp(ipod,s-oformat-name)) mov-mode = MODE_IPOD;
 -else if (!strcmp(ismv,s-oformat-name)) mov-mode = MODE_ISM;
  
 -mov_write_ftyp_tag(pb,s);
 -if (mov-mode == MODE_PSP) {
 -if (s-nb_streams != 2) {
 -av_log(s, AV_LOG_ERROR, PSP mode need one video and one 
 audio stream\n);
 -return -1;
 -}
 -mov_write_uuidprof_tag(pb, s);
 +mov_write_ftyp_tag(pb,s);
 +if (mov-mode == MODE_PSP) {
 +if (s-nb_streams != 2) {
 +av_log(s, AV_LOG_ERROR, PSP mode need one video and one audio 
 stream\n);
 +return -1;

While you are at it maybe return some AVERROR.


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

Re: [libav-devel] [PATCH 1/3] movenc: Set mov-mode earlier in mov_write_header

2013-09-21 Thread Luca Barbato
On 22/09/13 00:35, Martin Storsjö wrote:
 This allows simplifying some early checks that depend on the
 muxer mode.
 ---
  libavformat/movenc.c |   37 +++--
  1 file changed, 19 insertions(+), 18 deletions(-)

Beside the nit mentioned the set looks nice.
___
libav-devel mailing list
libav-devel@libav.org
https://lists.libav.org/mailman/listinfo/libav-devel