On 20 September 2013 14:15, Luca Barbato <[email protected]> wrote:
> Certain streaming server do not preserve the order of the fields.
> ---
>  libavformat/flvdec.c | 77 
> +++++++++++++++++++++++++++++++++++++++-------------
>  1 file changed, 58 insertions(+), 19 deletions(-)
>
> diff --git a/libavformat/flvdec.c b/libavformat/flvdec.c
> index b8feeaf..a923d20 100644
> --- a/libavformat/flvdec.c
> +++ b/libavformat/flvdec.c
> @@ -634,35 +634,73 @@ static void clear_index_entries(AVFormatContext *s, 
> int64_t pos)
>      }
>  }
>
> +static void amf_skip_tag(AVIOContext *pb, AMFDataType type)
> +{
> +    switch (type) {
> +    case AMF_DATA_TYPE_NUMBER:
> +        avio_skip(pb, 8);
> +        break;
> +    case AMF_DATA_TYPE_BOOL:
> +        avio_skip(pb, 1);
> +        break;
> +    case AMF_DATA_TYPE_STRING:
> +        avio_skip(pb, avio_rb16(pb));
> +        break;
> +    case AMF_DATA_TYPE_MIXEDARRAY:
> +        avio_skip(pb, 4);
> +    case AMF_DATA_TYPE_OBJECT:
> +        while(!pb->eof_reached) {
> +            int size = avio_rb16(pb);
> +            if (!size) {
> +                avio_skip(pb, 1);
> +                break;
> +            }
> +            avio_skip(pb, size);
> +            amf_skip_tag(pb, avio_r8(pb));
> +        }
> +        break;
> +    case AMF_DATA_TYPE_NULL:
> +    case AMF_DATA_TYPE_OBJECT_END:
> +    default:
> +        return;

Maybe print a warning here for other types that aren't supported, like
plain arrays? Because this would lead to weird results if such a type
were received (they wouldn't be skipped, and we'd check the next byte
as if it were another tag), so it'd be nice to have some idea of why.


> -    type = avio_r8(pb);
> -    if (type == AMF_DATA_TYPE_MIXEDARRAY)
> +    switch (avio_r8(pb)) {
> +    case AMF_DATA_TYPE_MIXEDARRAY:
>          avio_seek(pb, 4, SEEK_CUR);
> -    else if (type != AMF_DATA_TYPE_OBJECT)
> -        return AVERROR_INVALIDDATA;
> -
> -    amf_get_string(pb, buf, sizeof(buf));
> -    if (strcmp(buf, "type") || avio_r8(pb) != AMF_DATA_TYPE_STRING)
> -        return AVERROR_INVALIDDATA;
> +    case AMF_DATA_TYPE_OBJECT:
> +        break;
> +    default:
> +        goto skip;

Ditto for printing a warning, although it's probably less important here.

> +    }
>
> -    amf_get_string(pb, buf, sizeof(buf));
> -    // FIXME parse it as codec_id
> -    amf_get_string(pb, buf, sizeof(buf));
> -    if (strcmp(buf, "text") || avio_r8(pb) != AMF_DATA_TYPE_STRING)
> -        return AVERROR_INVALIDDATA;
> +    while ((ret = amf_get_string(pb, buf, sizeof(buf))) > 0) {
> +        AMFDataType type = avio_r8(pb);
> +        if (type == AMF_DATA_TYPE_STRING && !strcmp(buf, "text")) {
> +            length = avio_rb16(pb);
> +            ret    = av_get_packet(pb, pkt, length);
> +            if (ret < 0)
> +                goto skip;

Do we want to set ret to AVERROR(EIO) as in the old code? Although
that would mask any underlying errors which could be propagated from
av_get_packet.

The rest looks fine.

Josh
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to