Beispiel #1
0
static int flv_read_packet(AVFormatContext *s, AVPacket *pkt)
{
    FLVContext *flv = s->priv_data;
    int ret, i, type, size, flags;
    int stream_type=-1;
    int64_t next, pos;
    int64_t dts, pts = AV_NOPTS_VALUE;
    int av_uninit(channels);
    int av_uninit(sample_rate);
    AVStream *st = NULL;

    for(;; avio_skip(s->pb, 4)) { /* pkt size is repeated at end. skip it */
        pos = avio_tell(s->pb);
        type = avio_r8(s->pb);
        size = avio_rb24(s->pb);
        dts = avio_rb24(s->pb);
        dts |= avio_r8(s->pb) << 24;
        av_dlog(s, "type:%d, size:%d, dts:%"PRId64"\n", type, size, dts);
        if (url_feof(s->pb))
            return AVERROR_EOF;
        avio_skip(s->pb, 3); /* stream id, always 0 */
        flags = 0;

        if (flv->validate_next < flv->validate_count) {
            int64_t validate_pos = flv->validate_index[flv->validate_next].pos;
            if (pos == validate_pos) {
                if (FFABS(dts - flv->validate_index[flv->validate_next].dts) <=
                        VALIDATE_INDEX_TS_THRESH) {
                    flv->validate_next++;
                } else {
                    clear_index_entries(s, validate_pos);
                    flv->validate_count = 0;
                }
            } else if (pos > validate_pos) {
                clear_index_entries(s, validate_pos);
                flv->validate_count = 0;
            }
        }

        if(size == 0)
            continue;

        next= size + avio_tell(s->pb);

        if (type == FLV_TAG_TYPE_AUDIO) {
            stream_type=FLV_STREAM_TYPE_AUDIO;
            flags = avio_r8(s->pb);
            size--;
        } else if (type == FLV_TAG_TYPE_VIDEO) {
            stream_type=FLV_STREAM_TYPE_VIDEO;
            flags = avio_r8(s->pb);
            size--;
            if ((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_VIDEO_INFO_CMD)
                goto skip;
        } else if (type == FLV_TAG_TYPE_META) {
            if (size > 13+1+4 && dts == 0) { // Header-type metadata stuff
                flv_read_metabody(s, next);
                goto skip;
            } else if (dts != 0) { // Script-data "special" metadata frames - don't skip
                stream_type=FLV_STREAM_TYPE_DATA;
            } else {
                goto skip;
            }
        } else {
            av_log(s, AV_LOG_DEBUG, "skipping flv packet: type %d, size %d, flags %d\n", type, size, flags);
skip:
            avio_seek(s->pb, next, SEEK_SET);
            continue;
        }

        /* skip empty data packets */
        if (!size)
            continue;

        /* now find stream */
        for(i=0; i<s->nb_streams; i++) {
            st = s->streams[i];
            if (st->id == stream_type)
                break;
        }
        if(i == s->nb_streams) {
            av_log(s, AV_LOG_WARNING, "Stream discovered after head already parsed\n");
            st = create_stream(s, stream_type,
            (int[]) {
                AVMEDIA_TYPE_VIDEO, AVMEDIA_TYPE_AUDIO, AVMEDIA_TYPE_DATA
            }[stream_type]);
        }
        av_dlog(s, "%d %X %d \n", stream_type, flags, st->discard);
        if(  (st->discard >= AVDISCARD_NONKEY && !((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_KEY || (stream_type == FLV_STREAM_TYPE_AUDIO)))
                ||(st->discard >= AVDISCARD_BIDIR  &&  ((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_DISP_INTER && (stream_type == FLV_STREAM_TYPE_VIDEO)))
                || st->discard >= AVDISCARD_ALL
          ) {
            avio_seek(s->pb, next, SEEK_SET);
            continue;
        }
        if ((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_KEY)
            av_add_index_entry(st, pos, dts, size, 0, AVINDEX_KEYFRAME);
        break;
    }
Beispiel #2
0
static int ReadPacket(flv* p, format_reader* Reader, format_packet* Packet)
{
	format_stream* s;
    int		i, type, size, TimeStamp, flags, is_audio;
	int64_t next;
	bool_t	isNewStream = 0;
	filepos_t	startfilepos;
	
	startfilepos = Reader->FilePos;

	for (;;) 
	{
		Reader->Skip(Reader, 4);//prvious type size
		type = Reader->Read8(Reader);
		size = ReadBE24(Reader);
		TimeStamp = ReadBE24(Reader);
		if (Reader->Eof(Reader))
		{
			return ERR_END_OF_FILE;
		}

		// Reserved
		Reader->Skip(Reader, 4);

		flags = 0;

		if (size == 0)
			continue;

		next = size + Reader->FilePos;

		if (type == FLV_TAG_TYPE_AUDIO)
		{
			is_audio = 1;
			flags = Reader->Read8(Reader);
			size--;
			p->bHasA = 1;
		} 
		else if (type == FLV_TAG_TYPE_VIDEO)
		{
			is_audio = 0;
			flags = Reader->Read8(Reader);
			size--;
			p->bHasV = 1;
		}
		else if (type == FLV_TAG_TYPE_META && size > 13+1+4)
		{
			if(flv_read_metabody(p,Reader, next)<0)
			{
				Reader->Seek(Reader,(filepos_t)next,SEEK_SET);
			}
			continue;
		}
		else
		{
			// Skip the packet
			Reader->Skip(Reader, size);
			continue;
		}

		// Now find stream
		s = NULL;
		for (i=0;i<p->Format.StreamCount;++i)
		{
			if (p->Format.Streams[i]->Id == is_audio)
			{
				s = p->Format.Streams[i];
				break;
			}
		}

		if (!s)
		{
			s = Format_AddStream(&p->Format,sizeof(format_stream));
	        if (!s)
		        return ERR_OUT_OF_MEMORY;

			s->Id = is_audio;
			isNewStream = 1;

			s->Format.PacketRate.Den = 24;
			s->Format.PacketRate.Num = 1000;
		}

		break;
	}

    if(is_audio)
	{
		if (isNewStream)
		{
			int bInited = 0;

			PacketFormatClear(&s->Format);
			s->Format.Type = PACKET_AUDIO;
			s->Format.Format.Audio.Channels = (flags&1)+1;
			if((flags >> 4) == 5)
				s->Format.Format.Audio.SampleRate = 8000;
			else
				s->Format.Format.Audio.SampleRate = (44100<<((flags>>2)&3))>>3;

			switch(flags >> 4)
			{/* 0: uncompressed 1: ADPCM 2: mp3 5: Nellymoser 8kHz mono 6: Nellymoser */
			case FLV_CODECID_PCM:
				s->Format.Format.Audio.Format = AUDIOFMT_PCM;
				if (!(flags&2))
				{
					s->Format.Format.Audio.Bits = 8;
					s->Format.Format.Audio.FracBits = 7;
					bInited = 1;
				}
				break;
			case FLV_CODECID_ADPCM:
				s->Format.Format.Audio.Format = AUDIOFMT_ADPCM_SWF;
				break;
			case FLV_CODECID_MP3: 
				s->Format.Format.Audio.Format = AUDIOFMT_MP3;
				break;
			case FLV_CODECID_PCM_LE:
				s->Format.Format.Audio.Format = AUDIOFMT_PCM;
				if (!(flags&2))
				{
					s->Format.Format.Audio.Bits = 8;
					s->Format.Format.Audio.FracBits = 7;
					bInited = 1;
				}
				break;
			case FLV_CODECID_NELLYMOSER_8KHZ_MONO:
				s->Format.Format.Audio.SampleRate = 8000;
			case FLV_CODECID_NELLYMOSER:
				s->Format.Format.Audio.Format = AUDIOFMT_NELLYMOSER;
				break;
			case FLV_CODECID_AAC:
				{
					format_stream* s;
					int type = Reader->Read8(Reader);
					size--;
					if(type == 0)
					{
						s = p->Format.Streams[p->Format.StreamCount-1];

						if (PacketFormatExtra(&s->Format,size))
							Reader->Read(Reader,s->Format.Extra,size);
					}
					s->Format.Format.Audio.Format = AUDIOFMT_AAC;
					Format_PrepairStream(&p->Format, s);

				}
				return ERR_NONE;
			case FLV_CODECID_SPEEX:
				s->Format.Format.Audio.Format = AUDIOFMT_SPEEX;
				s->Format.Format.Audio.SampleRate = 16000;
				break;
			default:
				return ERR_NOT_SUPPORTED;
			}
			if(!bInited)
			{
				s->Format.Format.Audio.Bits = 16;
				s->Format.Format.Audio.FracBits = 15;
			}
			s->Format.ByteRate = s->Format.Format.Audio.SampleRate * s->Format.Format.Audio.Channels * 2;
			Format_PrepairStream(&p->Format,s);
		}
    }