ireader / media-server

RTSP/RTP/RTMP/FLV/HLS/MPEG-TS/MPEG-PS/MPEG-DASH/MP4/fMP4/MKV/WebM
MIT License
3.06k stars 1.07k forks source link

libflv flv_parser_input函数解析问题 #292

Closed BreakingY closed 1 year ago

BreakingY commented 1 year ago

作者你好,我看个代码块好像存在问题,求证 `case FLV_TAG_HEADER: n = flv_parser_append(parser, data, bytes, FLV_TAG_HEADER_SIZE); if (FLV_TAG_HEADER_SIZE == parser->bytes) { flv_tag_header_read(&parser->tag, parser->ptr, parser->bytes); parser->bytes = 0; parser->expect = 0; parser->state = FLV_AVHEADER_CODEC; } break;

    case FLV_AVHEADER_CODEC:
        switch (parser->tag.type)
        {
        case FLV_TYPE_AUDIO:
            parser->expect = 1;
            n = flv_parser_append(parser, data, bytes, 1);
            codec = (parser->ptr[0] & 0xF0) /*>> 4*/;
            if (FLV_AUDIO_AAC == codec || FLV_AUDIO_OPUS == codec)
                parser->expect = 2;
            break;

        case FLV_TYPE_VIDEO:
            parser->expect = 1;
            n = flv_parser_append(parser, data, bytes, 1);
            codec = (parser->ptr[0] & 0x0F);
            if (FLV_VIDEO_H264 == codec || FLV_VIDEO_H265 == codec || FLV_VIDEO_H266 == codec || FLV_VIDEO_AV1 == codec)
                parser->expect = 5;
            break;

        case FLV_TYPE_SCRIPT:
            parser->expect = 0;
            n = 0; // noops
            break;

        default:
            assert(0);
            return -1; // invalid flv file
        }
        parser->state = FLV_AVHEADER_EXTRA;
        break;`

这里是不是应该在parser->state = FLV_AVHEADER_EXTRA之前加上parser->bytes=0,如果不把parser->bytes置0,FLV_AVHEADER_EXTRA中调用flv_parser_append读取数据的时候,就是从parser->ptr[1]开始的,因为在FLV_AVHEADER_CODEC中已经flv_parser_append(parser, data, bytes, 1);,但是flv_audio_tag_header_read和flv_video_tag_header_read都是默认从parser->ptr[0]开始解析的 `case FLV_AVHEADER_EXTRA: n = flv_parser_append(parser, data, bytes, parser->expect); if (parser->expect == parser->bytes) { if(FLV_TYPE_AUDIO == parser->tag.type) flv_audio_tag_header_read(&parser->audio, parser->ptr, parser->bytes); else if(FLV_TYPE_VIDEO == parser->tag.type) flv_video_tag_header_read(&parser->video, parser->ptr, parser->bytes); parser->bytes = 0; parser->state = FLV_TAG_BODY;

            parser->expect = parser->tag.size - parser->expect;
            parser->body = parser->alloc ? parser->alloc(param, parser->expect) : malloc(parser->expect);
            if (!parser->body)
                return -1;
        }
        break;`
ireader commented 1 year ago

不是问题,extra data包含了FLV_AVHEADER_CODEC阶段的数据。

BreakingY commented 1 year ago

还是有点没明白 以Video Tag Data为例: |视频参数8bit|AVPacketType(8bit)|CompositionTime(24bit)|Video Data..

case FLV_AVHEADER_CODEC://此时data指向 ->|视频参数8bit|AVPacketType(8bit)|CompositionTime(24bit)|Video Data.. switch (parser->tag.type) { case FLV_TYPE_AUDIO: parser->expect = 1; n = flv_parser_append(parser, data, bytes, 1); codec = (parser->ptr[0] & 0xF0) />> 4/; if (FLV_AUDIO_AAC == codec || FLV_AUDIO_OPUS == codec) parser->expect = 2; break;

case FLV_TYPE_VIDEO:
    parser->expect = 1;
    n = flv_parser_append(parser, data, bytes, 1);//读取|视频参数8bit|到ptr[0]
    codec = (parser->ptr[0] & 0x0F);
    if (FLV_VIDEO_H264 == codec || FLV_VIDEO_H265 == codec || FLV_VIDEO_H266 == codec || FLV_VIDEO_AV1 == codec)
        parser->expect = 5;
    break;

case FLV_TYPE_SCRIPT:
    parser->expect = 0;
    n = 0; // noops
    break;

default:
    assert(0);
    return -1; // invalid flv file
}
parser->state = FLV_AVHEADER_EXTRA;
break;

此时parser->ptr[0] 保存|视频参数8bit| parser->bytes=1; n=1 下一次循环走到case FLV_AVHEADER_EXTRA的时候data指向->|AVPacketType(8bit)|CompositionTime(24bit)|Video Data..,需要4个字节把|AVPacketType(8bit)|CompositionTime(24bit)|读取出来,parser->expect应该等于4,但是这里parser->expect = 5;,有点没看明白.大佬勿笑,我太菜了,确实有点没看懂

ireader commented 1 year ago

image

FLV_TAG_HEADER包含了上面的内容, 从FLV_AVHEADER_CODEC开始处理AudioTagHeader/VideoTagHeader

BreakingY commented 1 year ago

我理解FLV_AVHEADER_CODEC开始是处理AudioTagHeader/VideoTagHeader,VideoTagHeader一共5个字节:|视频参数8bit|AVPacketType(8bit)|CompositionTime(24bit)|,case FLV_AVHEADER_CODEC里面n = flv_parser_append(parser, data, bytes, 1);读取了一个字节,下一次循环data后移1个字节,指定|AVPacketType(8bit)|CompositionTime(24bit)| 所以case FLV_AVHEADER_EXTRA:的时候应该只需要读取4个字节就可以了把

ireader commented 1 year ago

debug跑下代码,单步跟一下试试

BreakingY commented 1 year ago

嗯,可能是我理解不到位,我debug一下把