[FFmpeg-cvslog] avformat/argo_{asf,brp}: use variable frame sizes when (de)muxing adpcm_argo

Zane van Iperen git at videolan.org
Sat Sep 19 10:16:58 EEST 2020


ffmpeg | branch: master | Zane van Iperen <zane at zanevaniperen.com> | Wed Sep 16 07:39:51 2020 +1000| [52d362c6e0bc80ca191817cfac61f26d23d9cff3] | committer: Zane van Iperen

avformat/argo_{asf,brp}: use variable frame sizes when (de)muxing adpcm_argo

Signed-off-by: Zane van Iperen <zane at zanevaniperen.com>

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=52d362c6e0bc80ca191817cfac61f26d23d9cff3
---

 libavformat/argo_asf.c | 38 ++++++++++++++++++++++++++++----------
 libavformat/argo_brp.c |  2 +-
 2 files changed, 29 insertions(+), 11 deletions(-)

diff --git a/libavformat/argo_asf.c b/libavformat/argo_asf.c
index b1632f3ba5..048e5441d6 100644
--- a/libavformat/argo_asf.c
+++ b/libavformat/argo_asf.c
@@ -26,6 +26,9 @@
 #include "libavutil/opt.h"
 #include "argo_asf.h"
 
+/* Maximum number of blocks to read at once. */
+#define ASF_NB_BLOCKS 32
+
 typedef struct ArgoASFDemuxContext {
     ArgoASFFileHeader   fhdr;
     ArgoASFChunkHeader  ckhdr;
@@ -37,6 +40,7 @@ typedef struct ArgoASFMuxContext {
     int            version_major;
     int            version_minor;
     const char    *name;
+    int64_t        nb_blocks;
 } ArgoASFMuxContext;
 
 void ff_argo_asf_parse_file_header(ArgoASFFileHeader *hdr, const uint8_t *buf)
@@ -125,12 +129,10 @@ int ff_argo_asf_fill_stream(AVStream *st, const ArgoASFFileHeader *fhdr,
      * (nchannel control bytes) + ((bytes_per_channel) * nchannel)
      * For mono, this is 17. For stereo, this is 34.
      */
-    st->codecpar->frame_size            = st->codecpar->channels +
+    st->codecpar->block_align           = st->codecpar->channels +
                                           (ckhdr->num_samples / 2) *
                                           st->codecpar->channels;
 
-    st->codecpar->block_align           = st->codecpar->frame_size;
-
     st->codecpar->bit_rate              = st->codecpar->channels *
                                           st->codecpar->sample_rate *
                                           st->codecpar->bits_per_coded_sample;
@@ -221,15 +223,21 @@ static int argo_asf_read_packet(AVFormatContext *s, AVPacket *pkt)
     if (asf->blocks_read >= asf->ckhdr.num_blocks)
         return AVERROR_EOF;
 
-    if ((ret = av_get_packet(pb, pkt, st->codecpar->frame_size)) < 0)
+    ret = av_get_packet(pb, pkt, st->codecpar->block_align *
+                        FFMIN(ASF_NB_BLOCKS, asf->ckhdr.num_blocks - asf->blocks_read));
+    if (ret < 0)
         return ret;
-    else if (ret != st->codecpar->frame_size)
+
+    /* Something real screwy is going on. */
+    if (ret % st->codecpar->block_align != 0)
         return AVERROR_INVALIDDATA;
 
+
     pkt->stream_index   = st->index;
-    pkt->duration       = asf->ckhdr.num_samples;
+    pkt->duration       = asf->ckhdr.num_samples * (ret / st->codecpar->block_align);
+    asf->blocks_read   += (ret / st->codecpar->block_align);
 
-    ++asf->blocks_read;
+    pkt->flags &= ~AV_PKT_FLAG_CORRUPT;
     return 0;
 }
 
@@ -277,6 +285,9 @@ static int argo_asf_write_init(AVFormatContext *s)
         return AVERROR(EINVAL);
     }
 
+    if (par->block_align != 17 * par->channels)
+        return AVERROR(EINVAL);
+
     if (par->sample_rate > UINT16_MAX) {
         av_log(s, AV_LOG_ERROR, "Sample rate too large\n");
         return AVERROR(EINVAL);
@@ -364,24 +375,31 @@ static int argo_asf_write_header(AVFormatContext *s)
 
 static int argo_asf_write_packet(AVFormatContext *s, AVPacket *pkt)
 {
-    if (pkt->size != 17 * s->streams[0]->codecpar->channels)
+    ArgoASFMuxContext *ctx = s->priv_data;
+    AVCodecParameters *par = s->streams[0]->codecpar;
+    int nb_blocks = pkt->size / par->block_align;
+
+    if (pkt->size % par->block_align != 0)
         return AVERROR_INVALIDDATA;
 
-    if (s->streams[0]->nb_frames >= UINT32_MAX)
+    if (ctx->nb_blocks + nb_blocks > UINT32_MAX)
         return AVERROR_INVALIDDATA;
 
     avio_write(s->pb, pkt->data, pkt->size);
+
+    ctx->nb_blocks += nb_blocks;
     return 0;
 }
 
 static int argo_asf_write_trailer(AVFormatContext *s)
 {
+    ArgoASFMuxContext *ctx = s->priv_data;
     int64_t ret;
 
     if ((ret = avio_seek(s->pb, ASF_FILE_HEADER_SIZE, SEEK_SET) < 0))
         return ret;
 
-    avio_wl32(s->pb, (uint32_t)s->streams[0]->nb_frames);
+    avio_wl32(s->pb, (uint32_t)ctx->nb_blocks);
     return 0;
 }
 
diff --git a/libavformat/argo_brp.c b/libavformat/argo_brp.c
index 122f616ecc..27029d07b1 100644
--- a/libavformat/argo_brp.c
+++ b/libavformat/argo_brp.c
@@ -364,7 +364,7 @@ static int argo_brp_read_basf(AVFormatContext *s, AVPacket *pkt,
     else if (ret != brp->basf.offset)
         return AVERROR(EIO);
 
-    if ((ret = av_get_packet(s->pb, pkt, par->frame_size)) < 0)
+    if ((ret = av_get_packet(s->pb, pkt, par->block_align)) < 0)
         return ret;
 
     if ((ret = avio_seek(s->pb, old, SEEK_SET)) < 0)



More information about the ffmpeg-cvslog mailing list