[FFmpeg-devel] [PATCH] Fix: VP9 superframe parsing when the superframe contains only one frame

2015-11-06 Thread Sebastien Alaiwan
Hi,

The attached patch fixes an issue with the superframe index parsing.
Please find attached a VP9 IVF stream showing the issue (if you try to remux it 
to webm).
The gist of the problem is that the vp9 superframe parser seems to expect at 
least two frames inside the superframe.

Cheers,
Sebastien Alaiwan



superframe.vp9
Description: Binary data
From 2b9dccf27821f6de1e792bba3f340d2ba9a2753f Mon Sep 17 00:00:00 2001
From: Sebastien Alaiwan <sebastien.alai...@allegrodvt.com>
Date: Fri, 6 Nov 2015 14:29:12 +0100
Subject: [PATCH] Fix VP9 superframe parsing when there's only one nested frame
 in the superframe

Signed-off-by: Sebastien Alaiwan <sebastien.alai...@allegrodvt.com>
---
 libavcodec/vp9_parser.c | 92 ++---
 1 file changed, 41 insertions(+), 51 deletions(-)

diff --git a/libavcodec/vp9_parser.c b/libavcodec/vp9_parser.c
index 6713850..07c80da 100644
--- a/libavcodec/vp9_parser.c
+++ b/libavcodec/vp9_parser.c
@@ -88,65 +88,55 @@ static int parse(AVCodecParserContext *ctx,
 return 0;
 }
 
-if (s->n_frames > 0) {
-*out_data = data;
-*out_size = s->size[--s->n_frames];
-parse_frame(ctx, *out_data, *out_size);
+if (s->n_frames <= 0) {
 
-return s->n_frames > 0 ? *out_size : size /* i.e. include idx tail */;
-}
+// by default: exactly one nested frame, no index
+s->n_frames = 1;
+s->size[0] = full_size;
+
+// try to read many nested frames
+marker = data[size - 1];
+if ((marker & 0xe0) == 0xc0) {
+int nbytes = 1 + ((marker >> 3) & 0x3);
+int n_frames = 1 + (marker & 0x7);
+int idx_sz = 2 + n_frames * nbytes;
+
+if (size >= idx_sz && data[size - idx_sz] == marker) {
+const uint8_t *idx = data + size + 1 - idx_sz;
+
+s->n_frames = n_frames;
 
-marker = data[size - 1];
-if ((marker & 0xe0) == 0xc0) {
-int nbytes = 1 + ((marker >> 3) & 0x3);
-int n_frames = 1 + (marker & 0x7), idx_sz = 2 + n_frames * nbytes;
-
-if (size >= idx_sz && data[size - idx_sz] == marker) {
-const uint8_t *idx = data + size + 1 - idx_sz;
-int first = 1;
-
-switch (nbytes) {
-#define case_n(a, rd) \
-case a: \
-while (n_frames--) { \
-unsigned sz = rd; \
-idx += a; \
-if (sz == 0 || sz > size) { \
-s->n_frames = 0; \
-*out_size = size; \
-*out_data = data; \
-av_log(avctx, AV_LOG_ERROR, \
-   "Invalid superframe packet size: %u frame size: 
%d\n", \
-   sz, size); \
-return full_size; \
-} \
-if (first) { \
-first = 0; \
-*out_data = data; \
-*out_size = sz; \
-s->n_frames = n_frames; \
-} else { \
-s->size[n_frames] = sz; \
-} \
-data += sz; \
-size -= sz; \
-} \
-parse_frame(ctx, *out_data, *out_size); \
-return *out_size
-
-case_n(1, *idx);
-case_n(2, AV_RL16(idx));
-case_n(3, AV_RL24(idx));
-case_n(4, AV_RL32(idx));
+for(int k=0; k < n_frames; ++k) {
+unsigned sz = 0;
+
+for(int i=0; i < nbytes;++i)
+sz += idx[i] << (8*i);
+
+idx += nbytes;
+
+if (sz > size) {
+s->n_frames = 0;
+*out_size = size;
+*out_data = data;
+av_log(avctx, AV_LOG_ERROR,
+"Superframe packet size too big: %u > %d\n",
+sz, size);
+return full_size;
+}
+
+s->size[n_frames-1-k] = sz;
+}
 }
 }
 }
 
+assert(s->n_frames > 0);
+
 *out_data = data;
-*out_size = size;
-parse_frame(ctx, data, size);
+*out_size = s->size[--s->n_frames];
+parse_frame(ctx, *out_data, *out_size);
 
-return size;
+return s->n_frames > 0 ? *out_size : size /* i.e. include idx tail */;
 }
 
 AVCodecParser ff_vp9_parser = {
-- 
2.6.2

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


Re: [FFmpeg-devel] [PATCH] Fix: VP9 superframe parsing when the superframe contains only one frame

2015-11-06 Thread Sebastien Alaiwan
On 11/06/2015 05:37 PM, Ronald S. Bultje wrote:
> Hi,
>
> On Fri, Nov 6, 2015 at 11:10 AM, Sebastien Alaiwan <
> sebastien.alai...@allegrodvt.com> wrote:
>
>> Hi,
>>
>> The attached patch fixes an issue with the superframe index parsing.
>> Please find attached a VP9 IVF stream showing the issue (if you try to
>> remux it to webm).
>> The gist of the problem is that the vp9 superframe parser seems to expect
>> at least two frames inside the superframe.
>
> This is not OK, you rewrote the full parser and it looks like you simply 
> copied the libvpx code.
I did not. I simplified the flow of control of the existing code.
Would it be a problem anyway?




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