[rtmpdump] Patch: improve recovery by scanning forward following packet headers to find last valid packet offset

Martin Panter vadmium+rtmp at gmail.com
Thu Nov 13 05:06:02 CET 2014


I was just looking at this code (considering a resume function for a
HDS downloader), so I thought I would try and understand your patch as
well. It looks like this patch is intended to help resume a file with
an incomplete FLV tag at the end. Some comments below; hope they are
useful.

On 5 November 2014 00:04, Peter Pickford <rtmpdump at netremedies.ca> wrote:
> diff --git a/rtmpdump.c b/rtmpdump.c
> index 13741a7..5a69395 100644
> --- a/rtmpdump.c
> +++ b/rtmpdump.c
> @@ -303,8 +303,29 @@ GetLastKeyframe(FILE * file,       // output file [in]
>    // find the last seekable frame
>    off_t tsize = 0;
This initial value no longer used.

>    uint32_t prevTagSize = 0;
> +  uint32_t headerSize = 0;
> +  uint32_t payloadSize = 0;
> +  off_t offset = 0;
> +  off_t lastGoodTag = 0;
>
>    // go through the file and find the last video keyframe
> +  fseek(file, 5, SEEK_SET);
This seek shouldn’t be necessary because the flags byte at offset 4
was just read a few lines up.

> +  if (fread(buffer, 1, 4, file) != 4) {
> +       RTMP_Log(RTMP_LOGERROR, "Couldn't read headerSize from file!");
> +       return RD_FAILED;
> +  }
> +  headerSize = AMF_DecodeInt32(buffer);
> +  offset = headerSize;
> +  while (offset < size) {
What if headerSize >= size? The lastGoodTag = 0 initial value isn’t
going to help.

> +       fseeko(file, offset + 5, SEEK_SET);
> +       if (fread(buffer, 1, 4, file) != 4) {
The fourth byte isn’t used is it? This alarmed me until I realized you
were still only decoding 3 bytes further down.

> +               break;
> +       }
> +       payloadSize = AMF_DecodeInt24(buffer);
> +       lastGoodTag = offset;

What if the file is truncated in the middle of this “last good tag”,
and some of the payload is missing? Maybe you should also check that
the end offset (below) is within the total file size. (Unless you
meant this to point to the first bad tag.)

> +       offset += payloadSize + 15; // the back pointer the tag header
> and the payload
> +  }
> +  tsize = size - lastGoodTag - 4; // set tsize to point to offset
> from end of file of the header of last good tag
Previously “tsize” was the offset of the _end_ of the last tag from
EOF (i.e. zero). Now I think you are making it the offset of the
_start_ of the “last good tag” (i.e. end of 2nd last good tag).

>    do
>      {
>        int xread;


More information about the rtmpdump mailing list