These files are technically a series of planar mono tracks. If the "music" flag is set, merge the packets from the two mono tracks, essentially replicating:
[0:a:0][0:a:1]join=inputs=2:channel_layout=stereo[a] Signed-off-by: Zane van Iperen <z...@zanevaniperen.com> --- libavformat/pp_bnk.c | 60 ++++++++++++++++++++++++++++++++++++-------- 1 file changed, 50 insertions(+), 10 deletions(-) diff --git a/libavformat/pp_bnk.c b/libavformat/pp_bnk.c index 8364de1fd9..970ef09923 100644 --- a/libavformat/pp_bnk.c +++ b/libavformat/pp_bnk.c @@ -55,6 +55,8 @@ typedef struct PPBnkCtx { int track_count; PPBnkCtxTrack *tracks; uint32_t current_track; + int is_music; + AVPacket pkt; } PPBnkCtx; enum { @@ -194,8 +196,12 @@ static int pp_bnk_read_header(AVFormatContext *s) goto fail; } + ctx->is_music = (hdr.flags & PP_BNK_FLAG_MUSIC) && + (ctx->track_count == 2) && + (ctx->tracks[0].data_size == ctx->tracks[1].data_size); + /* Build the streams. */ - for (int i = 0; i < ctx->track_count; i++) { + for (int i = 0; i < (ctx->is_music ? 1 : ctx->track_count); i++) { if (!(st = avformat_new_stream(s, NULL))) { ret = AVERROR(ENOMEM); goto fail; @@ -204,14 +210,21 @@ static int pp_bnk_read_header(AVFormatContext *s) par = st->codecpar; par->codec_type = AVMEDIA_TYPE_AUDIO; par->codec_id = AV_CODEC_ID_ADPCM_IMA_CUNNING; - par->format = AV_SAMPLE_FMT_S16; - par->channel_layout = AV_CH_LAYOUT_MONO; - par->channels = 1; + par->format = AV_SAMPLE_FMT_S16P; + + if (ctx->is_music) { + par->channel_layout = AV_CH_LAYOUT_STEREO; + par->channels = 2; + } else { + par->channel_layout = AV_CH_LAYOUT_MONO; + par->channels = 1; + } + par->sample_rate = hdr.sample_rate; par->bits_per_coded_sample = 4; par->bits_per_raw_sample = 16; par->block_align = 1; - par->bit_rate = par->sample_rate * par->bits_per_coded_sample; + par->bit_rate = par->sample_rate * par->bits_per_coded_sample * par->channels; avpriv_set_pts_info(st, 64, 1, par->sample_rate); st->start_time = 0; @@ -253,7 +266,22 @@ static int pp_bnk_read_packet(AVFormatContext *s, AVPacket *pkt) size = FFMIN(trk->data_size - trk->bytes_read, PP_BNK_MAX_READ_SIZE); - if ((ret = av_get_packet(s->pb, pkt, size)) == AVERROR_EOF) { + if (!ctx->is_music) + ret = av_new_packet(&ctx->pkt, size); + else if (ctx->current_track == 0) + ret = av_new_packet(&ctx->pkt, size * 2); + else + ret = 0; + + if (ret < 0) + return ret; + + if (ctx->is_music) + ret = avio_read(s->pb, ctx->pkt.data + size * ctx->current_track, size); + else + ret = avio_read(s->pb, ctx->pkt.data, size); + + if (ret == AVERROR_EOF) { /* If we've hit EOF, don't attempt this track again. */ trk->data_size = trk->bytes_read; continue; @@ -261,10 +289,21 @@ static int pp_bnk_read_packet(AVFormatContext *s, AVPacket *pkt) return ret; } - trk->bytes_read += ret; - pkt->flags &= ~AV_PKT_FLAG_CORRUPT; - pkt->stream_index = ctx->current_track++; - pkt->duration = ret * 2; + trk->bytes_read += ret; + ctx->pkt.flags &= ~AV_PKT_FLAG_CORRUPT; + ctx->pkt.stream_index = ctx->current_track++; + ctx->pkt.duration = ret * 2; + + if (ctx->is_music) { + if (ctx->pkt.stream_index == 0) + return FFERROR_REDO; + + ctx->pkt.stream_index = 0; + } else { + ctx->pkt.size = ret; + } + + av_packet_move_ref(pkt, &ctx->pkt); return 0; } @@ -277,6 +316,7 @@ static int pp_bnk_read_close(AVFormatContext *s) PPBnkCtx *ctx = s->priv_data; av_freep(&ctx->tracks); + av_packet_unref(&ctx->pkt); return 0; } -- 2.29.3 _______________________________________________ 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".