[FFmpeg-devel] avformat/matroska: Parse generic encryption info from packets.

Submitted by James Almer on Aug. 14, 2018, 3:50 a.m.

Details

Message ID c93d5ac2-b4d7-9e43-4c41-6f3273637a62@gmail.com
State New
Headers show

Commit Message

James Almer Aug. 14, 2018, 3:50 a.m.
On 7/12/2018 8:45 PM, Jacob Trimble wrote:
> I am currently seeing a problem with this when using Opus audio.  In
> read_frame_internal, it will try to parse the resulting packet.  For
> video, which uses subsample encryption, it is able to parse the
> headers; but for Opus, which uses full-sample encryption, it fails to
> parse the headers.  This causes the read_frame_internal to drop the
> packet.
> 
> I have traced a workaround to opus_parse in opus_parser.c: instead of
> setting poutbuf to NULL, set it to the buffer and just pass the packet
> to the app to handle it.  The frame will be decrypted before passing
> to the decoder.  I can't just disable parsing in the demuxer because I
> want to parse the packets for clear content and when using subsample
> encryption.
> 
> Does anyone have any other ideas to work around this?  Is there a way
> to allow parsing but ignore errors?

Try the attached diff to see if it fixes the issue (It makes the parser
not bother trying to assemble packets from what could be incomplete data
if the source is a demuxer that guarantees the propagation of complete
packets).

Comments

James Almer Aug. 14, 2018, 3:53 a.m.
On 8/14/2018 12:50 AM, James Almer wrote:
> On 7/12/2018 8:45 PM, Jacob Trimble wrote:
>> I am currently seeing a problem with this when using Opus audio.  In
>> read_frame_internal, it will try to parse the resulting packet.  For
>> video, which uses subsample encryption, it is able to parse the
>> headers; but for Opus, which uses full-sample encryption, it fails to
>> parse the headers.  This causes the read_frame_internal to drop the
>> packet.
>>
>> I have traced a workaround to opus_parse in opus_parser.c: instead of
>> setting poutbuf to NULL, set it to the buffer and just pass the packet
>> to the app to handle it.  The frame will be decrypted before passing
>> to the decoder.  I can't just disable parsing in the demuxer because I
>> want to parse the packets for clear content and when using subsample
>> encryption.
>>
>> Does anyone have any other ideas to work around this?  Is there a way
>> to allow parsing but ignore errors?
> Try the attached diff to see if it fixes the issue (It makes the parser
> not bother trying to assemble packets from what could be incomplete data
> if the source is a demuxer that guarantees the propagation of complete
> packets).
> 
> 
> opus.diff
> 
> 
> diff --git a/libavcodec/opus_parser.c b/libavcodec/opus_parser.c
> index 28b0933900..e8d157356c 100644
> --- a/libavcodec/opus_parser.c
> +++ b/libavcodec/opus_parser.c
> @@ -170,6 +170,9 @@ static int opus_parse(AVCodecParserContext *ctx, AVCodecContext *avctx,
>      ParseContext *pc    = &s->pc;
>      int next, header_len;

Err, with the change below this should be initialized to 0 now. Sorry.

>  
> +    if (s->flags & PARSER_FLAG_COMPLETE_FRAMES) {
> +        next = buf_size;
> +    } else {
>      next = opus_find_frame_end(ctx, avctx, buf, buf_size, &header_len);
>  
>      if (s->ts_framing && next != AVERROR_INVALIDDATA &&
> @@ -184,6 +187,7 @@ static int opus_parse(AVCodecParserContext *ctx, AVCodecContext *avctx,
>          *poutbuf_size = 0;
>          return buf_size;
>      }
> +    }
>  
>      *poutbuf      = buf + header_len;
>      *poutbuf_size = buf_size - header_len;
>
Jacob Trimble Aug. 20, 2018, 6:38 p.m.
On Mon, Aug 13, 2018 at 9:01 PM James Almer <jamrial@gmail.com> wrote:
>
> On 8/14/2018 12:50 AM, James Almer wrote:
> > On 7/12/2018 8:45 PM, Jacob Trimble wrote:
> >> I am currently seeing a problem with this when using Opus audio.  In
> >> read_frame_internal, it will try to parse the resulting packet.  For
> >> video, which uses subsample encryption, it is able to parse the
> >> headers; but for Opus, which uses full-sample encryption, it fails to
> >> parse the headers.  This causes the read_frame_internal to drop the
> >> packet.
> >>
> >> I have traced a workaround to opus_parse in opus_parser.c: instead of
> >> setting poutbuf to NULL, set it to the buffer and just pass the packet
> >> to the app to handle it.  The frame will be decrypted before passing
> >> to the decoder.  I can't just disable parsing in the demuxer because I
> >> want to parse the packets for clear content and when using subsample
> >> encryption.
> >>
> >> Does anyone have any other ideas to work around this?  Is there a way
> >> to allow parsing but ignore errors?
> > Try the attached diff to see if it fixes the issue (It makes the parser
> > not bother trying to assemble packets from what could be incomplete data
> > if the source is a demuxer that guarantees the propagation of complete
> > packets).
> >

Yep that fixed it, thanks.  I sent out a patch to implement that
(since other parsers do it, it seems like the correct thing to do).

In that case, this patch works well and is ready to review/merge.

> >
> > opus.diff
> >
> >
> > diff --git a/libavcodec/opus_parser.c b/libavcodec/opus_parser.c
> > index 28b0933900..e8d157356c 100644
> > --- a/libavcodec/opus_parser.c
> > +++ b/libavcodec/opus_parser.c
> > @@ -170,6 +170,9 @@ static int opus_parse(AVCodecParserContext *ctx, AVCodecContext *avctx,
> >      ParseContext *pc    = &s->pc;
> >      int next, header_len;
>
> Err, with the change below this should be initialized to 0 now. Sorry.
>
> >
> > +    if (s->flags & PARSER_FLAG_COMPLETE_FRAMES) {
> > +        next = buf_size;
> > +    } else {
> >      next = opus_find_frame_end(ctx, avctx, buf, buf_size, &header_len);
> >
> >      if (s->ts_framing && next != AVERROR_INVALIDDATA &&
> > @@ -184,6 +187,7 @@ static int opus_parse(AVCodecParserContext *ctx, AVCodecContext *avctx,
> >          *poutbuf_size = 0;
> >          return buf_size;
> >      }
> > +    }
> >
> >      *poutbuf      = buf + header_len;
> >      *poutbuf_size = buf_size - header_len;
> >
>
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel

Patch hide | download patch | download mbox

diff --git a/libavcodec/opus_parser.c b/libavcodec/opus_parser.c
index 28b0933900..e8d157356c 100644
--- a/libavcodec/opus_parser.c
+++ b/libavcodec/opus_parser.c
@@ -170,6 +170,9 @@  static int opus_parse(AVCodecParserContext *ctx, AVCodecContext *avctx,
     ParseContext *pc    = &s->pc;
     int next, header_len;
 
+    if (s->flags & PARSER_FLAG_COMPLETE_FRAMES) {
+        next = buf_size;
+    } else {
     next = opus_find_frame_end(ctx, avctx, buf, buf_size, &header_len);
 
     if (s->ts_framing && next != AVERROR_INVALIDDATA &&
@@ -184,6 +187,7 @@  static int opus_parse(AVCodecParserContext *ctx, AVCodecContext *avctx,
         *poutbuf_size = 0;
         return buf_size;
     }
+    }
 
     *poutbuf      = buf + header_len;
     *poutbuf_size = buf_size - header_len;