/*
 * MPEG1/2 demuxer
 * Copyright (c) 2000, 2001, 2002 Fabrice Bellard
 *
 * This file is part of FFmpeg.
 *
 * FFmpeg is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * FFmpeg is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with FFmpeg; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

#include "avformat.h"
#include "mpeg.h"

//#define DEBUG_SEEK

#undef NDEBUG
#include <assert.h>

/*********************************************/
/* demux code */

#define MAX_SYNC_SIZE 100000

static int check_pes(uint8_t *p, uint8_t *end){
    int pes1;
    int pes2=      (p[3] & 0xC0) == 0x80
                && (p[4] & 0xC0) != 0x40
                &&((p[4] & 0xC0) == 0x00 || (p[4]&0xC0)>>2 == (p[6]&0xF0));

    for(p+=3; p<end && *p == 0xFF; p++);
    if((*p&0xC0) == 0x40) p+=2;
    if((*p&0xF0) == 0x20){
        pes1= p[0]&p[2]&p[4]&1;
        p+=5;
    }else if((*p&0xF0) == 0x30){
        pes1= p[0]&p[2]&p[4]&p[5]&p[7]&p[9]&1;
        p+=10;
    }else
        pes1 = *p == 0x0F;

    return pes1||pes2;
}

static int mpegps_probe(AVProbeData *p)
{
    uint32_t code= -1;
    int sys=0, pspack=0, priv1=0, vid=0, audio=0, invalid=0;
    int i;
    int score=0;

    for(i=0; i<p->buf_size; i++){
        code = (code<<8) + p->buf[i];
        if ((code & 0xffffff00) == 0x100) {
            int pes= check_pes(p->buf+i, p->buf+p->buf_size);

            if(code == SYSTEM_HEADER_START_CODE) sys++;
            else if(code == PRIVATE_STREAM_1)    priv1++;
            else if(code == PACK_START_CODE)     pspack++;
            else if((code & 0xf0) == VIDEO_ID &&  pes) vid++;
            else if((code & 0xe0) == AUDIO_ID &&  pes) audio++;

            else if((code & 0xf0) == VIDEO_ID && !pes) invalid++;
            else if((code & 0xe0) == AUDIO_ID && !pes) invalid++;
        }
    }

    if(vid+audio > invalid)     /* invalid VDR files nd short PES streams */
        score= AVPROBE_SCORE_MAX/4;

//av_log(NULL, AV_LOG_ERROR, "%d %d %d %d %d len:%d\n", sys, priv1, pspack,vid, audio, p->buf_size);
    if(sys>invalid && sys*9 <= pspack*10)
        return AVPROBE_SCORE_MAX/2+2; // +1 for .mpg
    if(priv1 + vid + audio > invalid && (priv1+vid+audio)*9 <= pspack*10)
        return AVPROBE_SCORE_MAX/2+2; // +1 for .mpg
// STV version    if((!!vid ^ !!audio) && (audio+vid > 7) && !sys && !pspack && p->buf_size>2048) /* PES stream */
    if((!!vid ^ !!audio) && (audio > 4 || vid > 1) && !sys && !pspack && p->buf_size>2048) /* PES stream */
        return AVPROBE_SCORE_MAX/2+2;

    //02-Penguin.flac has sys:0 priv1:0 pspack:0 vid:0 audio:1
	// NARFLEX: I've seen FLAC files with audio:2, so let's set it higher for safety
    return score;
}


typedef struct MpegDemuxContext {
    int32_t header_state;
    unsigned char psm_es_type[256];
    int sofdec;
} MpegDemuxContext;

static int mpegps_read_header(AVFormatContext *s,
                              AVFormatParameters *ap)
{
    MpegDemuxContext *m = s->priv_data;
    const char *sofdec = "Sofdec";
    int v, i = 0;

    m->header_state = 0xff;
    s->ctx_flags |= AVFMTCTX_NOHEADER;

    m->sofdec = -1;
    do {
        v = get_byte(s->pb);
        m->header_state = m->header_state << 8 | v;
        m->sofdec++;
    } while (v == sofdec[i] && i++ < 6);

    /* no need to do more */
    return 0;
}

static int64_t get_pts(ByteIOContext *pb, int c)
{
    uint8_t buf[5];
	int64_t rv;
	
    buf[0] = c<0 ? get_byte(pb) : c;
    get_buffer(pb, buf+1, 4);
	
	rv = ff_parse_pes_pts(buf);
	
	if (rv > (0x200000000LL - 30LL*90000LL))
	{
		// NARFLEX: This is in here to deal with MPEG2 files I keep running into that start with timestamps
		// that are just about to rollover at 2^33 at the start of the file
		// (a half second of audio usually at the start before it rolls over, and the video starts at zero)
		rv = rv - 0x200000000LL;
	}
	return rv;
}

static int find_next_start_code(ByteIOContext *pb, int *size_ptr,
                                int32_t *header_state)
{
    unsigned int state, v;
    int val, n;

    state = *header_state;
    n = *size_ptr;
    while (n > 0) {
        if (url_feof(pb))
            break;
        v = get_byte(pb);
        n--;
        if (state == 0x000001) {
            state = ((state << 8) | v) & 0xffffff;
            val = state;
            goto found;
        }
        state = ((state << 8) | v) & 0xffffff;
    }
    val = -1;
 found:
    *header_state = state;
    *size_ptr = n;
    return val;
}

#if 0 /* unused, remove? */
/* XXX: optimize */
static int find_prev_start_code(ByteIOContext *pb, int *size_ptr)
{
    int64_t pos, pos_start;
    int max_size, start_code;

    max_size = *size_ptr;
    pos_start = url_ftell(pb);

    /* in order to go faster, we fill the buffer */
    pos = pos_start - 16386;
    if (pos < 0)
        pos = 0;
    url_fseek(pb, pos, SEEK_SET);
    get_byte(pb);

    pos = pos_start;
    for(;;) {
        pos--;
        if (pos < 0 || (pos_start - pos) >= max_size) {
            start_code = -1;
            goto the_end;
        }
        url_fseek(pb, pos, SEEK_SET);
        start_code = get_be32(pb);
        if ((start_code & 0xffffff00) == 0x100)
            break;
    }
 the_end:
    *size_ptr = pos_start - pos;
    return start_code;
}
#endif

/**
 * Extracts stream types from a program stream map
 * According to ISO/IEC 13818-1 ('MPEG-2 Systems') table 2-35
 *
 * @return number of bytes occupied by PSM in the bitstream
 */
static long mpegps_psm_parse(MpegDemuxContext *m, ByteIOContext *pb)
{
    int psm_length, ps_info_length, es_map_length;

    psm_length = get_be16(pb);
    get_byte(pb);
    get_byte(pb);
    ps_info_length = get_be16(pb);

    /* skip program_stream_info */
    url_fskip(pb, ps_info_length);
    es_map_length = get_be16(pb);

    /* at least one es available? */
    while (es_map_length >= 4){
        unsigned char type      = get_byte(pb);
        unsigned char es_id     = get_byte(pb);
        uint16_t es_info_length = get_be16(pb);
        /* remember mapping from stream id to stream type */
        m->psm_es_type[es_id] = type;
        /* skip program_stream_info */
        url_fskip(pb, es_info_length);
        es_map_length -= 4 + es_info_length;
    }
    get_be32(pb); /* crc32 */
    return 2 + psm_length;
}

/* read the next PES header. Return its position in ppos
   (if not NULL), and its start code, pts and dts.
 */
static int mpegps_read_pes_header(AVFormatContext *s,
                                  int64_t *ppos, int *pstart_code,
                                  int64_t *ppts, int64_t *pdts)
{
    MpegDemuxContext *m = s->priv_data;
    int len, size, startcode, c, flags, header_len;
    int pes_ext, ext2_len, id_ext, skip;
    int64_t pts, dts;
    int64_t last_sync= url_ftell(s->pb);

 error_redo:
        url_fseek(s->pb, last_sync, SEEK_SET);
 redo:
        /* next start code (should be immediately after) */
        m->header_state = 0xff;
        size = MAX_SYNC_SIZE;
        startcode = find_next_start_code(s->pb, &size, &m->header_state);
        last_sync = url_ftell(s->pb);
//    av_log(NULL, AV_LOG_DEBUG, "startcode=%x pos=0x%"PRIx64"\n", startcode, url_ftell(s->pb));
    if (startcode < 0)
        return AVERROR(EIO);
    if (startcode == PACK_START_CODE)
        goto redo;
    if (startcode == SYSTEM_HEADER_START_CODE)
        goto redo;
    if (startcode == PADDING_STREAM) {
        url_fskip(s->pb, get_be16(s->pb));
        goto redo;
    }
    if (startcode == PRIVATE_STREAM_2) {
        len = get_be16(s->pb);
        if (!m->sofdec) {
            while (len-- >= 6) {
                if (get_byte(s->pb) == 'S') {
                    uint8_t buf[5];
                    get_buffer(s->pb, buf, sizeof(buf));
                    m->sofdec = !memcmp(buf, "ofdec", 5);
                    len -= sizeof(buf);
                    break;
                }
            }
            m->sofdec -= !m->sofdec;
        }
        url_fskip(s->pb, len);
        goto redo;
    }
    if (startcode == PROGRAM_STREAM_MAP) {
        mpegps_psm_parse(m, s->pb);
        goto redo;
    }

	/* STV: special case broken PS files produced by a bug in our muxer that created 0x00000100 start codes on some audio PES packets */
	if(startcode == 0x100) {
		int64_t loc = url_ftell(s->pb); 	// so we can rewind if necessary
		int nextstart;
		uint32_t hstate = 0xff;
		len = get_be16(s->pb);
		url_fskip(s->pb, len);	// skip past invalid PES packet (but has valid size)
		
		// check for valid start code
		size = 8;
		nextstart = find_next_start_code(s->pb, &size, &hstate);
		if(nextstart != -1) {
			// found valid start code, rewind a bit and goto redo
			last_sync = loc + len;
			goto error_redo;
		}
		
		// probably just a corrupt stream, rewind and resume
		url_fseek(s->pb, loc, SEEK_SET);
		goto redo;
	}
	
    /* find matching stream */
    if (!((startcode >= 0x1c0 && startcode <= 0x1df) ||
          (startcode >= 0x1e0 && startcode <= 0x1ef) ||
          (startcode == 0x1bd) || (startcode == 0x1fa) || (startcode == 0x1fd)))
        goto redo;
    if (ppos) {
        *ppos = url_ftell(s->pb) - 4;
    }
    len = get_be16(s->pb);
    pts =
    dts = AV_NOPTS_VALUE;
    /* stuffing */
    for(;;) {
        if (len < 1)
            goto error_redo;
        c = get_byte(s->pb);
        len--;
        /* XXX: for mpeg1, should test only bit 7 */
        if (c != 0xff)
            break;
    }
    if ((c & 0xc0) == 0x40) {
        /* buffer scale & size */
        get_byte(s->pb);
        c = get_byte(s->pb);
        len -= 2;
    }
    if ((c & 0xe0) == 0x20) {
        /*dts =*/ pts = get_pts(s->pb, c);
        len -= 4;
        if (c & 0x10){
            dts = get_pts(s->pb, -1);
            len -= 5;
        }
    } else if ((c & 0xc0) == 0x80) {
        /* mpeg 2 PES */
#if 0 /* some streams have this field set for no apparent reason */
        if ((c & 0x30) != 0) {
            /* Encrypted multiplex not handled */
            goto redo;
        }
#endif
        flags = get_byte(s->pb);
        header_len = get_byte(s->pb);
        len -= 2;
        if (header_len > len)
            goto error_redo;
        len -= header_len;
        if (flags & 0x80) {
            /*dts =*/ pts = get_pts(s->pb, -1);
            header_len -= 5;
            if (flags & 0x40) {
                dts = get_pts(s->pb, -1);
                header_len -= 5;
            }
        }
        if (flags & 0x3f && header_len == 0){
            flags &= 0xC0;
            av_log(s, AV_LOG_WARNING, "Further flags set but no bytes left\n");
        }
        if (flags & 0x01) { /* PES extension */
            pes_ext = get_byte(s->pb);
            header_len--;
            /* Skip PES private data, program packet sequence counter and P-STD buffer */
            skip = (pes_ext >> 4) & 0xb;
            skip += skip & 0x9;
            if (pes_ext & 0x40 || skip > header_len){
                av_log(s, AV_LOG_WARNING, "pes_ext %X is invalid\n", pes_ext);
                pes_ext=skip=0;
            }
            url_fskip(s->pb, skip);
            header_len -= skip;

            if (pes_ext & 0x01) { /* PES extension 2 */
                ext2_len = get_byte(s->pb);
                header_len--;
                if ((ext2_len & 0x7f) > 0) {
                    id_ext = get_byte(s->pb);
                    if ((id_ext & 0x80) == 0)
                        startcode = ((startcode & 0xff) << 8) | id_ext;
                    header_len--;
                }
            }
        }
        if(header_len < 0)
            goto error_redo;
        url_fskip(s->pb, header_len);
    }
    else if( c!= 0xf )
        goto redo;

	// NARFLEX - I have no idea why they don't strip off the audio header junk
	// if there's a PSM. I guess they assume then those headers aren't there; but that
	// don't work for our PSMs
    if (startcode == PRIVATE_STREAM_1 /*&& !m->psm_es_type[startcode & 0xff]*/) {
        startcode = get_byte(s->pb);
        len--;
        if (startcode >= 0x80 && startcode <= 0xcf) {
            /* audio: skip header */
            get_byte(s->pb);
            get_byte(s->pb);
            get_byte(s->pb);
            len -= 3;
            if (startcode >= 0xb0 && startcode <= 0xbf) {
                /* MLP/TrueHD audio has a 4-byte header */
                get_byte(s->pb);
                len--;
            }
        }
    }
    if(len<0)
        goto error_redo;
    if(dts != AV_NOPTS_VALUE && ppos){
        int i;
        for(i=0; i<s->nb_streams; i++){
            if(startcode == s->streams[i]->id &&
               !url_is_streamed(s->pb) /* index useless on streams anyway */) {
                ff_reduce_index(s, i);
                av_add_index_entry(s->streams[i], *ppos, dts, 0, 0, AVINDEX_KEYFRAME /* FIXME keyframe? */);
            }
        }
    }

    *pstart_code = startcode;
    *ppts = pts;
    *pdts = dts;
    return len;
}

static int mpegps_read_packet(AVFormatContext *s,
                              AVPacket *pkt)
{
    MpegDemuxContext *m = s->priv_data;
    AVStream *st;
    int len, startcode, i, es_type;
    enum CodecID codec_id = CODEC_ID_NONE;
    enum CodecType type;
    int64_t pts, dts, dummy_pos; //dummy_pos is needed for the index building to work
    uint8_t av_uninit(dvdaudio_substream_type);

 redo:
    len = mpegps_read_pes_header(s, &dummy_pos, &startcode, &pts, &dts);
    if (len < 0)
        return len;

    if(startcode == 0x1bd) {
        dvdaudio_substream_type = get_byte(s->pb);
        url_fskip(s->pb, 3);
        len -= 4;
    }

    /* now find stream */
    for(i=0;i<s->nb_streams;i++) {
        st = s->streams[i];
        if (st->id == startcode)
            goto found;
    }

    es_type = m->psm_es_type[startcode & 0xff];
    if(es_type > 0 && es_type != STREAM_TYPE_PRIVATE_DATA){
        if(es_type == STREAM_TYPE_VIDEO_MPEG1){
            codec_id = CODEC_ID_MPEG2VIDEO;
            type = CODEC_TYPE_VIDEO;
        } else if(es_type == STREAM_TYPE_VIDEO_MPEG2){
            codec_id = CODEC_ID_MPEG2VIDEO;
            type = CODEC_TYPE_VIDEO;
        } else if(es_type == STREAM_TYPE_AUDIO_MPEG1 ||
                  es_type == STREAM_TYPE_AUDIO_MPEG2){
            codec_id = CODEC_ID_MP3;
            type = CODEC_TYPE_AUDIO;
        } else if(es_type == STREAM_TYPE_AUDIO_AAC){
            codec_id = CODEC_ID_AAC;
            type = CODEC_TYPE_AUDIO;
        } else if(es_type == STREAM_TYPE_AUDIO_AAC_LATM){
            codec_id = CODEC_ID_AAC_LATM;
            type = CODEC_TYPE_AUDIO;
        } else if(es_type == STREAM_TYPE_VIDEO_MPEG4){
            codec_id = CODEC_ID_MPEG4;
            type = CODEC_TYPE_VIDEO;
        } else if(es_type == STREAM_TYPE_VIDEO_H264){
            codec_id = CODEC_ID_H264;
            type = CODEC_TYPE_VIDEO;
        } else if(es_type == STREAM_TYPE_AUDIO_AC3){
            codec_id = CODEC_ID_AC3;
            type = CODEC_TYPE_AUDIO;
        } else {
            goto skip;
        }
    } else if (startcode >= 0x1e0 && startcode <= 0x1ef) {
        static const unsigned char avs_seqh[4] = { 0, 0, 1, 0xb0 };
        unsigned char buf[8];
        get_buffer(s->pb, buf, 8);
        url_fseek(s->pb, -8, SEEK_CUR);
        if(!memcmp(buf, avs_seqh, 4) && (buf[6] != 0 || buf[7] != 1))
            codec_id = CODEC_ID_CAVS;
        else
            codec_id = CODEC_ID_PROBE;
        type = CODEC_TYPE_VIDEO;
    } else if (startcode >= 0x1c0 && startcode <= 0x1df) {
        type = CODEC_TYPE_AUDIO;
        codec_id = m->sofdec > 0 ? CODEC_ID_ADPCM_ADX : CODEC_ID_MP2;
    } else if (startcode >= 0x80 && startcode <= 0x87) {
        type = CODEC_TYPE_AUDIO;
        codec_id = CODEC_ID_AC3;
    } else if (  ( startcode >= 0x88 && startcode <= 0x8f)
               ||( startcode >= 0x98 && startcode <= 0x9f)) {
        /* 0x90 - 0x97 is reserved for SDDS in DVD specs */
        type = CODEC_TYPE_AUDIO;
        codec_id = CODEC_ID_DTS;
    } else if (startcode >= 0xa0 && startcode <= 0xaf) {
        type = CODEC_TYPE_AUDIO;
        /* 16 bit form will be handled as CODEC_ID_PCM_S16BE */
        codec_id = CODEC_ID_PCM_DVD;
    } else if (startcode >= 0xb0 && startcode <= 0xbf) {
        type = CODEC_TYPE_AUDIO;
        codec_id = CODEC_ID_TRUEHD;
    } else if (startcode >= 0xc0 && startcode <= 0xcf) {
        /* Used for both AC-3 and E-AC-3 in EVOB files */
        type = CODEC_TYPE_AUDIO;
        codec_id = CODEC_ID_AC3;
    } else if (startcode >= 0x20 && startcode <= 0x3f) {
        type = CODEC_TYPE_SUBTITLE;
        codec_id = CODEC_ID_DVD_SUBTITLE;
    } else if (startcode >= 0xfd55 && startcode <= 0xfd5f) {
        type = CODEC_TYPE_VIDEO;
        codec_id = CODEC_ID_VC1;
    } else if (startcode == 0x1bd) {
        // check dvd audio substream type
        type = CODEC_TYPE_AUDIO;
        switch(dvdaudio_substream_type & 0xe0) {
        case 0xa0:  codec_id = CODEC_ID_PCM_DVD;
                    break;
        case 0x80:  if((dvdaudio_substream_type & 0xf8) == 0x88)
                         codec_id = CODEC_ID_DTS;
                    else codec_id = CODEC_ID_AC3;
                    break;
        default:    av_log(s, AV_LOG_ERROR, "Unknown 0x1bd sub-stream\n");
                    goto skip;
        }
    } else {
    skip:
        /* skip packet */
        url_fskip(s->pb, len);
        goto redo;
    }
    /* no stream found: add a new stream */
    st = av_new_stream(s, startcode);
    if (!st)
        goto skip;
    st->codec->codec_type = type;
    st->codec->codec_id = codec_id;
    if (codec_id != CODEC_ID_PCM_S16BE)
        st->need_parsing = AVSTREAM_PARSE_FULL;
 found:
    if(st->discard >= AVDISCARD_ALL)
        goto skip;
    if ((startcode >= 0xa0 && startcode <= 0xaf) ||
        (startcode == 0x1bd && ((dvdaudio_substream_type & 0xe0) == 0xa0))) {
        int b1, freq;

        /* for LPCM, we just skip the header and consider it is raw
           audio data */
        if (len <= 3)
            goto skip;
        get_byte(s->pb); /* emphasis (1), muse(1), reserved(1), frame number(5) */
        b1 = get_byte(s->pb); /* quant (2), freq(2), reserved(1), channels(3) */
        get_byte(s->pb); /* dynamic range control (0x80 = off) */
        len -= 3;
        freq = (b1 >> 4) & 3;
        st->codec->sample_rate = lpcm_freq_tab[freq];
        st->codec->channels = 1 + (b1 & 7);
        st->codec->bits_per_coded_sample = 16 + ((b1 >> 6) & 3) * 4;
        st->codec->bit_rate = st->codec->channels *
                              st->codec->sample_rate *
                              st->codec->bits_per_coded_sample;
        if (st->codec->bits_per_coded_sample == 16)
            st->codec->codec_id = CODEC_ID_PCM_S16BE;
        else if (st->codec->bits_per_coded_sample == 28)
            return AVERROR(EINVAL);
    }
    av_new_packet(pkt, len);
    get_buffer(s->pb, pkt->data, pkt->size);
    pkt->pts = pts;
    pkt->dts = dts;
    pkt->stream_index = st->index;
#if 0
    av_log(s, AV_LOG_DEBUG, "%d: pts=%0.3f dts=%0.3f size=%d\n",
           pkt->stream_index, pkt->pts / 90000.0, pkt->dts / 90000.0, pkt->size);
#endif

    return 0;
}

static int64_t mpegps_read_dts(AVFormatContext *s, int stream_index,
                               int64_t *ppos, int64_t pos_limit)
{
    int len, startcode;
    int64_t pos, pts, dts;

    pos = *ppos;
#ifdef DEBUG_SEEK
    printf("read_dts: pos=0x%"PRIx64" next=%d -> ", pos, find_next);
#endif
    if (url_fseek(s->pb, pos, SEEK_SET) < 0)
        return AV_NOPTS_VALUE;

    for(;;) {
        len = mpegps_read_pes_header(s, &pos, &startcode, &pts, &dts);
        if (len < 0) {
#ifdef DEBUG_SEEK
            printf("none (ret=%d)\n", len);
#endif
            return AV_NOPTS_VALUE;
        }
        if (startcode == s->streams[stream_index]->id &&
            dts != AV_NOPTS_VALUE) {
            break;
        }
        url_fskip(s->pb, len);
    }
#ifdef DEBUG_SEEK
    printf("pos=0x%"PRIx64" dts=0x%"PRIx64" %0.3f\n", pos, dts, dts / 90000.0);
#endif
    *ppos = pos;
    return dts;
}

AVInputFormat mpegps_demuxer = {
    "mpeg",
    NULL_IF_CONFIG_SMALL("MPEG-PS format"),
    sizeof(MpegDemuxContext),
    mpegps_probe,
    mpegps_read_header,
    mpegps_read_packet,
    NULL,
    NULL, //mpegps_read_seek,
    mpegps_read_dts,
    .flags = AVFMT_SHOW_IDS|AVFMT_TS_DISCONT,
};
