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