Support decoding only a selection of the encoded XMA streams. Previously, the decoder assumed it was decoding all available streams. --- libavcodec/wmaprodec.c | 65 ++++++++++++++++++++++++------------------ 1 file changed, 38 insertions(+), 27 deletions(-)
diff --git a/libavcodec/wmaprodec.c b/libavcodec/wmaprodec.c index 66271c4037..b957b1d1ea 100644 --- a/libavcodec/wmaprodec.c +++ b/libavcodec/wmaprodec.c @@ -1814,7 +1814,44 @@ static int xma_decode_packet(AVCodecContext *avctx, void *data, XMADecodeCtx *s = avctx->priv_data; int got_stream_frame_ptr = 0; AVFrame *frame = data; - int i, ret, offset = INT_MAX; + int i, ret, skip_current_packet; + int offset = INT_MAX; + + /* find the owner stream of the new XMA packet that belongs to on of our streams + * XMA streams find their packets following packet_skips + * there may be other packets in between if we are not responsible for all streams + * (at start there is one packet per stream, then interleave non-linearly). */ + if (s->xma[s->current_stream].packet_done || + s->xma[s->current_stream].packet_loss) { + /* select stream with lowest skip_packets (= uses next packet) */ + if (s->xma[s->current_stream].skip_packets != 0) { + int min[2]; + + min[0] = s->xma[0].skip_packets; + min[1] = i = 0; + + for (i = 1; i < s->num_streams; i++) { + if (s->xma[i].skip_packets < min[0]) { + min[0] = s->xma[i].skip_packets; + min[1] = i; + } + } + + s->current_stream = min[1]; + } + + skip_current_packet = !!s->xma[s->current_stream].skip_packets; + + /* advance all stream packet skip counts */ + for (i = 0; i < s->num_streams; i++) { + s->xma[i].skip_packets = FFMAX(0, s->xma[i].skip_packets - 1); + } + + /* if we are not responsible for every stream, make sure we ignore + * XMA packets not belonging to one of our streams */ + if (skip_current_packet) + return avctx->block_align; + } if (!s->frames[s->current_stream]->data[0]) { s->frames[s->current_stream]->nb_samples = 512; @@ -1846,34 +1883,8 @@ static int xma_decode_packet(AVCodecContext *avctx, void *data, return ret; } - /* find next XMA packet's owner stream, and update. - * XMA streams find their packets following packet_skips - * (at start there is one packet per stream, then interleave non-linearly). */ if (s->xma[s->current_stream].packet_done || s->xma[s->current_stream].packet_loss) { - - /* select stream with 0 skip_packets (= uses next packet) */ - if (s->xma[s->current_stream].skip_packets != 0) { - int min[2]; - - min[0] = s->xma[0].skip_packets; - min[1] = i = 0; - - for (i = 1; i < s->num_streams; i++) { - if (s->xma[i].skip_packets < min[0]) { - min[0] = s->xma[i].skip_packets; - min[1] = i; - } - } - - s->current_stream = min[1]; - } - - /* all other streams skip next packet */ - for (i = 0; i < s->num_streams; i++) { - s->xma[i].skip_packets = FFMAX(0, s->xma[i].skip_packets - 1); - } - /* copy samples from buffer to output if possible */ for (i = 0; i < s->num_streams; i++) { offset = FFMIN(offset, s->offset[i]); -- 2.30.2 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".