please disregard v3 patch ... `if (size <= 10 || size % 2 != 0)` statement is wrong, I've submitted a v4 patch to correct it.
Thank you, Pavel. On Thu, Feb 13, 2025 at 2:01 PM Pavel Koshevoy <pkoshe...@gmail.com> wrote: > The problem is reproducible with "Test for Quicktime 608 CC file.mov" > from https://samples.ffmpeg.org/MPEG2/subcc/ > > ffmpeg -i "Test for Quicktime 608 CC file.mov" -map 0 -c copy -y > remuxed.mov > > Prior to the fix QuickTime Player playback of remuxed.mov would > render garbage text for "English CC" subtitles. > --- > libavformat/mov.c | 68 ++++++++++++++++++++++++++++++++++++++++------- > 1 file changed, 58 insertions(+), 10 deletions(-) > > diff --git a/libavformat/mov.c b/libavformat/mov.c > index 85aef33b19..84165735f7 100644 > --- a/libavformat/mov.c > +++ b/libavformat/mov.c > @@ -10790,23 +10790,71 @@ static int mov_change_extradata(AVStream *st, > AVPacket *pkt) > > static int get_eia608_packet(AVIOContext *pb, AVPacket *pkt, int size) > { > - int new_size, ret; > + /* We can't make assumptions about the structure of the payload, > + because it may include multiple cdat and cdt2 samples. */ > + const uint32_t cdat = AV_RB32("cdat"); > + const uint32_t cdt2 = AV_RB32("cdt2"); > + int ret, out_size = 0; > + > + /* a valid payload must have size, 4cc, and at least 1 byte pair: */ > + if (size <= 10 || size % 2 != 0) > + return AVERROR_INVALIDDATA; > > - if (size <= 8) > + /* avoid an int overflow: */ > + if ((size - 8) / 2 >= INT_MAX / 3) > return AVERROR_INVALIDDATA; > - new_size = ((size - 8) / 2) * 3; > - ret = av_new_packet(pkt, new_size); > + > + ret = av_new_packet(pkt, ((size - 8) / 2) * 3); > if (ret < 0) > return ret; > > - avio_skip(pb, 8); > - for (int j = 0; j < new_size; j += 3) { > - pkt->data[j] = 0xFC; > - pkt->data[j+1] = avio_r8(pb); > - pkt->data[j+2] = avio_r8(pb); > + /* parse and re-format the c608 payload in one pass. */ > + while (size >= 10) { > + const uint32_t atom_size = avio_rb32(pb); > + const uint32_t atom_type = avio_rb32(pb); > + const int32_t data_size = atom_size - 8; > + const uint8_t cc_field = > + atom_type == cdat ? 1 : > + atom_type == cdt2 ? 2 : > + 0; > + > + /* account for bytes consumed for atom size and type. */ > + size -= 8; > + > + /* make sure the atom size stays within the buffer boundaries. */ > + if (data_size < 2 || data_size > size) { > + ret = AVERROR_INVALIDDATA; > + break; > + } > + > + /* make sure the payload size is consistent with N byte pairs. */ > + if (atom_size % 2 != 0) { > + ret = AVERROR_INVALIDDATA; > + break; > + } > + > + if (!cc_field) { > + /* neither cdat or cdt2 ... skip it */ > + avio_skip(pb, data_size); > + size -= data_size; > + continue; > + } > + > + for (int32_t i = 0; i < data_size; i += 2) { > + pkt->data[out_size] = (0x1F << 3) | (1 << 2) | (cc_field - 1); > + pkt->data[out_size + 1] = avio_r8(pb); > + pkt->data[out_size + 2] = avio_r8(pb); > + out_size += 3; > + size -= 2; > + } > } > > - return 0; > + if (size > 0) > + /* skip any remaining unread portion of the input payload */ > + avio_skip(pb, size); > + > + av_shrink_packet(pkt, out_size); > + return ret; > } > > static int mov_finalize_packet(AVFormatContext *s, AVStream *st, > AVIndexEntry *sample, > -- > 2.43.0 > > _______________________________________________ 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".