Message ID | c93d5ac2-b4d7-9e43-4c41-6f3273637a62@gmail.com |
---|---|
State | New |
Headers | show |
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; >
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
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;