On Fri, Jun 01, 2018 at 07:00:20AM +0000, Eran Kornblau wrote: > > On Thu, May 31, 2018 at 10:11:38AM +0000, Eran Kornblau wrote: > > > > > > > > -----Original Message----- > > > > From: ffmpeg-devel [mailto:ffmpeg-devel-boun...@ffmpeg.org] On > > > > Behalf Of Eran Kornblau > > > > Sent: Friday, May 25, 2018 4:40 PM > > > > To: FFmpeg development discussions and patches > > > > <ffmpeg-devel@ffmpeg.org> > > > > Subject: [FFmpeg-devel] qt-faststart bug near 4GB > > > > > > > > Hi all, > > > > > > > > We encountered a rather extreme edge case with qt-faststart - we > > > > transcoded some video with ffmpeg, and the offset of the last video > > > > frame in the resulting mp4 was slightly less than 4GB. > > > > Since it was less than 4GB, ffmpeg used an 'stco' atom and not a 'co64' > > > > atom. > > > > When we ran qt-faststart on this file, it added the moov atom size to > > > > all offsets in the 'stco' atom, causing an overflow in the offsets of > > > > the frames close to the end of the file. The end of the video was > > > > therefore corrupt and could not be played. > > > > I think the solution here is to 'upgrade' the 'stco' atom to 'co64' if > > > > such an edge case happens. However, looking at the code of > > > > qt-faststart, I see that it doesn't actually parse the atom tree, but > > > > rather looks for the strings 'stco' / 'co64'. Changing 'stco' to 'co64' > > > > requires updating the size of all the atom in which it's contained > > > > (moov, trak, mdia etc.) Therefore, such a change would probably be more > > > > of a rewrite of this utility than a patch, so wanted to check whether > > > > anyone has any thoughts on this before I start writing... > > > > > > > Attaching the patch for this issue. > > > As expected, it required significant changes... hope you will like it > > > :) > > > > > > Thanks! > > > > > > Eran > > > > about the AV_WB* macros, i like them alot :) but this seems not to apply > > cleanly: > > > > Applying: qt-faststart - stco offset bug fix Using index info to > > reconstruct a base tree... > > M tools/qt-faststart.c > > Falling back to patching base and 3-way merge... > > Auto-merging tools/qt-faststart.c > > CONFLICT (content): Merge conflict in tools/qt-faststart.c > > error: Failed to merge in the changes. > > Patch failed at 0001 qt-faststart - stco offset bug fix Use 'git am > > --show-current-patch' to see the failed patch When you have resolved this > > problem, run "git am --continue". > > If you prefer to skip this patch, run "git am --skip" instead. > > To restore the original branch and stop patching, run "git am --abort". > > > Sorry Michael, I forgot to revert the previous patch before committing. > Attaching a fixed patch. > > Thanks > > Eran > > > [...] > > > > -- > > Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB > > > > Into a blind darkness they enter who follow after the Ignorance, they as if > > into a greater darkness enter who devote themselves to the Knowledge alone. > > -- Isha Upanishad > >
> qt-faststart.c | 400 > +++++++++++++++++++++++++++++++++++++++++++++++++-------- > 1 file changed, 345 insertions(+), 55 deletions(-) > e4e6ca876f190a354031d269b53655effa0eaa20 > 0001-qt-faststart-stco-offset-bug-fix.patch > From be7f3b43f5039297809dd88ead218e2523769064 Mon Sep 17 00:00:00 2001 > From: erankor <eran.kornb...@kaltura.com> > Date: Fri, 1 Jun 2018 09:55:45 +0300 > Subject: [PATCH] qt-faststart - stco offset bug fix > > when the last offsets in the stco atom are close to 4GB, the addition of > the moov atom size can overflow, causing corruption near the end of the > mp4 file. > this patch upgrades all stco atoms to co64 when such an edge case is > detected. in order to accomplish this, the implementation was changed to > walk the atom tree, instead of searching for the strings 'stco'/'co64'. > this was required since when an stco atom is changed to co64, its size > changes, and the sizes of all containing atoms (moov, trak, etc.) have > to be updated as well. > --- > tools/qt-faststart.c | 400 > ++++++++++++++++++++++++++++++++++++++++++++------- > 1 file changed, 345 insertions(+), 55 deletions(-) > > diff --git a/tools/qt-faststart.c b/tools/qt-faststart.c > index d0ae7245f3..40eb3fcfc8 100644 > --- a/tools/qt-faststart.c > +++ b/tools/qt-faststart.c > @@ -28,6 +28,7 @@ > #include <stdlib.h> > #include <inttypes.h> > #include <string.h> > +#include <limits.h> > > #ifdef __MINGW32__ > #undef fseeko > @@ -43,8 +44,6 @@ > > #define MIN(a,b) ((a) > (b) ? (b) : (a)) > > -#define BE_16(x) ((((uint8_t*)(x))[0] << 8) | ((uint8_t*)(x))[1]) > - > #define BE_32(x) (((uint32_t)(((uint8_t*)(x))[0]) << 24) | \ > (((uint8_t*)(x))[1] << 16) | \ > (((uint8_t*)(x))[2] << 8) | \ > @@ -59,6 +58,18 @@ > ((uint64_t)(((uint8_t*)(x))[6]) << 8) | \ > ((uint64_t)( (uint8_t*)(x))[7])) > > +#define AV_WB32(p, val) { \ > + ((uint8_t*)(p))[0] = ((val) >> 24) & 0xff; \ > + ((uint8_t*)(p))[1] = ((val) >> 16) & 0xff; \ > + ((uint8_t*)(p))[2] = ((val) >> 8) & 0xff; \ > + ((uint8_t*)(p))[3] = (val) & 0xff; \ > + } > + > +#define AV_WB64(p, val) { \ > + AV_WB32(p, (val) >> 32) \ > + AV_WB32(p + 4, val) \ > + } > + > #define BE_FOURCC(ch0, ch1, ch2, ch3) \ > ( (uint32_t)(unsigned char)(ch3) | \ > ((uint32_t)(unsigned char)(ch2) << 8) | \ > @@ -79,12 +90,342 @@ > #define UUID_ATOM QT_ATOM('u', 'u', 'i', 'd') > > #define CMOV_ATOM QT_ATOM('c', 'm', 'o', 'v') > +#define TRAK_ATOM QT_ATOM('t', 'r', 'a', 'k') > +#define MDIA_ATOM QT_ATOM('m', 'd', 'i', 'a') > +#define MINF_ATOM QT_ATOM('m', 'i', 'n', 'f') > +#define STBL_ATOM QT_ATOM('s', 't', 'b', 'l') > #define STCO_ATOM QT_ATOM('s', 't', 'c', 'o') > #define CO64_ATOM QT_ATOM('c', 'o', '6', '4') > > #define ATOM_PREAMBLE_SIZE 8 > #define COPY_BUFFER_SIZE 33554432 > > +typedef struct { > + uint32_t type; > + uint32_t header_size; > + uint64_t size; > + unsigned char *data; > +} atom_t; > + > +typedef struct { > + uint64_t moov_atom_size; > + uint64_t stco_offset_count; > + uint64_t stco_data_size; > + int stco_overflow; > + uint32_t depth; > +} update_chunk_offsets_context_t; > + > +typedef struct { > + unsigned char *dest; > + uint64_t original_moov_size; > + uint64_t new_moov_size; > +} upgrade_stco_context_t; > + > +typedef int (*parse_atoms_callback_t)(void *context, atom_t *atom); > + > +static int parse_atoms( > + unsigned char *buf, > + uint64_t size, > + parse_atoms_callback_t callback, > + void *context) > +{ > + unsigned char *pos = buf; > + unsigned char *end = pos + size; > + atom_t atom; > + int ret; > + > + while (end - pos >= ATOM_PREAMBLE_SIZE) { > + atom.size = BE_32(pos); > + atom.type = BE_32(pos + 4); > + pos += ATOM_PREAMBLE_SIZE; > + atom.header_size = ATOM_PREAMBLE_SIZE; > + > + switch (atom.size) { > + case 1: > + if (end - pos < 8) { > + printf("not enough room for 64 bit atom size\n"); > + return -1; > + } > + > + atom.size = BE_64(pos); > + pos += 8; > + atom.header_size = ATOM_PREAMBLE_SIZE + 8; > + break; > + > + case 0: > + atom.size = ATOM_PREAMBLE_SIZE + end - pos; > + break; > + } > + > + if (atom.size < atom.header_size) { > + printf("atom size %"PRIu64" too small\n", atom.size); errors should go to stderr if av_log() is not used i see this is not introduced by the patch but was that way before so its more a comment about the code in git than the patch ... but ideally this should be fixed in a seperate patch either before or after this one some self test for the newly added feature would also be a good idea also, was the new code tested with a fuzzer ? thx [...] -- Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB Frequently ignored answer#1 FFmpeg bugs should be sent to our bugtracker. User questions about the command line tools should be sent to the ffmpeg-user ML. And questions about how to use libav* should be sent to the libav-user ML.
signature.asc
Description: PGP signature
_______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel