Ejemplo n.º 1
0
int ff_mp4_read_dec_config_descr(AVFormatContext *fc, AVStream *st, AVIOContext *pb)
{
    enum AVCodecID codec_id;
    unsigned v;
    int len, tag;
    int ret;
    int object_type_id = avio_r8(pb);
    avio_r8(pb); /* stream type */
    avio_rb24(pb); /* buffer size db */

    v = avio_rb32(pb);

    // TODO: fix this with codecpar
#if FF_API_LAVF_AVCTX
FF_DISABLE_DEPRECATION_WARNINGS
    if (v < INT32_MAX)
        st->codec->rc_max_rate = v;
FF_ENABLE_DEPRECATION_WARNINGS
#endif

    st->codecpar->bit_rate = avio_rb32(pb); /* avg bitrate */

    codec_id= ff_codec_get_id(ff_mp4_obj_type, object_type_id);
    if (codec_id)
        st->codecpar->codec_id = codec_id;
    av_log(fc, AV_LOG_TRACE, "esds object type id 0x%02x\n", object_type_id);
    len = ff_mp4_read_descr(fc, pb, &tag);
    if (tag == MP4DecSpecificDescrTag) {
        av_log(fc, AV_LOG_TRACE, "Specific MPEG-4 header len=%d\n", len);
        if (!len || (uint64_t)len > (1<<30))
            return -1;
        av_free(st->codecpar->extradata);
        if ((ret = ff_get_extradata(fc, st->codecpar, pb, len)) < 0)
            return ret;
        if (st->codecpar->codec_id == AV_CODEC_ID_AAC) {
            MPEG4AudioConfig cfg = {0};
            avpriv_mpeg4audio_get_config(&cfg, st->codecpar->extradata,
                                         st->codecpar->extradata_size * 8, 1);
            st->codecpar->channels = cfg.channels;
            if (cfg.object_type == 29 && cfg.sampling_index < 3) // old mp3on4
                st->codecpar->sample_rate = avpriv_mpa_freq_tab[cfg.sampling_index];
            else if (cfg.ext_sample_rate)
                st->codecpar->sample_rate = cfg.ext_sample_rate;
            else
                st->codecpar->sample_rate = cfg.sample_rate;
            av_log(fc, AV_LOG_TRACE, "mp4a config channels %d obj %d ext obj %d "
                    "sample rate %d ext sample rate %d\n", st->codecpar->channels,
                    cfg.object_type, cfg.ext_object_type,
                    cfg.sample_rate, cfg.ext_sample_rate);
            if (!(st->codecpar->codec_id = ff_codec_get_id(mp4_audio_types,
                                                        cfg.object_type)))
                st->codecpar->codec_id = AV_CODEC_ID_AAC;
        }
    }
    return 0;
}
Ejemplo n.º 2
0
int ff_mp4_read_dec_config_descr(AVFormatContext *fc, AVStream *st, AVIOContext *pb)
{
    enum AVCodecID codec_id;
    int len, tag;
    int ret;
    int object_type_id = avio_r8(pb);
    avio_r8(pb); /* stream type */
    avio_rb24(pb); /* buffer size db */
    avio_rb32(pb); /* max bitrate */
    avio_rb32(pb); /* avg bitrate */

    if(avcodec_is_open(st->codec)) {
        av_log(fc, AV_LOG_DEBUG, "codec open in read_dec_config_descr\n");
        return -1;
    }

    codec_id= ff_codec_get_id(ff_mp4_obj_type, object_type_id);
    if (codec_id)
        st->codec->codec_id= codec_id;
    av_log(fc, AV_LOG_TRACE, "esds object type id 0x%02x\n", object_type_id);
    len = ff_mp4_read_descr(fc, pb, &tag);
    if (tag == MP4DecSpecificDescrTag) {
        av_log(fc, AV_LOG_TRACE, "Specific MPEG4 header len=%d\n", len);
        if (!len || (uint64_t)len > (1<<30))
            return -1;
        av_free(st->codec->extradata);
        if ((ret = ff_get_extradata(st->codec, pb, len)) < 0)
            return ret;
        if (st->codec->codec_id == AV_CODEC_ID_AAC) {
            MPEG4AudioConfig cfg = {0};
            avpriv_mpeg4audio_get_config(&cfg, st->codec->extradata,
                                         st->codec->extradata_size * 8, 1);
            st->codec->channels = cfg.channels;
            if (cfg.object_type == 29 && cfg.sampling_index < 3) // old mp3on4
                st->codec->sample_rate = avpriv_mpa_freq_tab[cfg.sampling_index];
            else if (cfg.ext_sample_rate)
                st->codec->sample_rate = cfg.ext_sample_rate;
            else
                st->codec->sample_rate = cfg.sample_rate;
            av_log(fc, AV_LOG_TRACE, "mp4a config channels %d obj %d ext obj %d "
                    "sample rate %d ext sample rate %d\n", st->codec->channels,
                    cfg.object_type, cfg.ext_object_type,
                    cfg.sample_rate, cfg.ext_sample_rate);
            if (!(st->codec->codec_id = ff_codec_get_id(mp4_audio_types,
                                                        cfg.object_type)))
                st->codec->codec_id = AV_CODEC_ID_AAC;
        }
    }
    return 0;
}
Ejemplo n.º 3
0
static int avr_read_header(AVFormatContext *s)
{
    uint16_t chan, sign, bps;
    AVStream *st;

    st = avformat_new_stream(s, NULL);
    if (!st)
        return AVERROR(ENOMEM);

    st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;

    avio_skip(s->pb, 4); // magic
    avio_skip(s->pb, 8); // sample_name

    chan = avio_rb16(s->pb);
    if (!chan) {
        st->codecpar->channels = 1;
    } else if (chan == 0xFFFFu) {
        st->codecpar->channels = 2;
    } else {
        avpriv_request_sample(s, "chan %d", chan);
        return AVERROR_PATCHWELCOME;
    }

    st->codecpar->bits_per_coded_sample = bps = avio_rb16(s->pb);

    sign = avio_rb16(s->pb);

    avio_skip(s->pb, 2); // loop
    avio_skip(s->pb, 2); // midi
    avio_skip(s->pb, 1); // replay speed

    st->codecpar->sample_rate = avio_rb24(s->pb);
    avio_skip(s->pb, 4 * 3);
    avio_skip(s->pb, 2 * 3);
    avio_skip(s->pb, 20);
    avio_skip(s->pb, 64);

    st->codecpar->codec_id = ff_get_pcm_codec_id(bps, 0, 1, sign);
    if (st->codecpar->codec_id == AV_CODEC_ID_NONE) {
        avpriv_request_sample(s, "Bps %d and sign %d", bps, sign);
        return AVERROR_PATCHWELCOME;
    }

    st->codecpar->block_align = bps * st->codecpar->channels / 8;

    avpriv_set_pts_info(st, 64, 1, st->codecpar->sample_rate);
    return 0;
}
Ejemplo n.º 4
0
/**
 * Try to find Xing/Info/VBRI tags and compute duration from info therein
 */
static int mp3_parse_vbr_tags(AVFormatContext *s, AVStream *st, int64_t base)
{
    MP3Context *mp3 = s->priv_data;
    uint32_t v, spf;
    unsigned frames = 0; /* Total number of frames in file */
    unsigned size = 0; /* Total number of bytes in the stream */
    const int64_t xing_offtbl[2][2] = {{32, 17}, {17,9}};
    MPADecodeHeader c;
    int vbrtag_size = 0;
    int is_cbr;

    v = avio_rb32(s->pb);
    if(ff_mpa_check_header(v) < 0)
      return -1;

    if (avpriv_mpegaudio_decode_header(&c, v) == 0)
        vbrtag_size = c.frame_size;
    if(c.layer != 3)
        return -1;

    spf = c.lsf ? 576 : 1152; /* Samples per frame, layer 3 */

    /* Check for Xing / Info tag */
    avio_skip(s->pb, xing_offtbl[c.lsf == 1][c.nb_channels == 1]);
    v = avio_rb32(s->pb);
    is_cbr = v == MKBETAG('I', 'n', 'f', 'o');
    if (v == MKBETAG('X', 'i', 'n', 'g') || is_cbr) {
        v = avio_rb32(s->pb);
        if(v & XING_FLAG_FRAMES)
            frames = avio_rb32(s->pb);
        if(v & XING_FLAG_SIZE)
            size = avio_rb32(s->pb);
        if (v & XING_FLAG_TOC && frames)
            read_xing_toc(s, size, av_rescale_q(frames, (AVRational){spf, c.sample_rate},
                                    st->time_base));
        if(v & 8)
            avio_skip(s->pb, 4);

        v = avio_rb32(s->pb);
        if(v == MKBETAG('L', 'A', 'M', 'E') || v == MKBETAG('L', 'a', 'v', 'f')) {
            avio_skip(s->pb, 21-4);
            v= avio_rb24(s->pb);
            mp3->start_pad = v>>12;
            mp3->  end_pad = v&4095;
            st->skip_samples = mp3->start_pad + 528 + 1;
            av_log(s, AV_LOG_DEBUG, "pad %d %d\n", mp3->start_pad, mp3->  end_pad);
        }
Ejemplo n.º 5
0
int ff_mp4_read_dec_config_descr(AVFormatContext *fc, AVStream *st, AVIOContext *pb)
{
	int len, tag;
	int object_type_id = avio_r8(pb);
	avio_r8(pb); /* stream type */
	avio_rb24(pb); /* buffer size db */
	avio_rb32(pb); /* max bitrate */
	avio_rb32(pb); /* avg bitrate */

	st->codec->codec_id= ff_codec_get_id(ff_mp4_obj_type, object_type_id);
	av_dlog(fc, "esds object type id 0x%02x\n", object_type_id);
	len = ff_mp4_read_descr(fc, pb, &tag);
	if (tag == MP4DecSpecificDescrTag)
	{
		av_dlog(fc, "Specific MPEG4 header len=%d\n", len);
		if((uint64_t)len > (1<<30))
			return -1;
		av_free(st->codec->extradata);
		st->codec->extradata = av_mallocz(len + FF_INPUT_BUFFER_PADDING_SIZE);
		if (!st->codec->extradata)
			return AVERROR(ENOMEM);
		avio_read(pb, st->codec->extradata, len);
		st->codec->extradata_size = len;
		if (st->codec->codec_id == CODEC_ID_AAC)
		{
			MPEG4AudioConfig cfg;
			ff_mpeg4audio_get_config(&cfg, st->codec->extradata,
			                         st->codec->extradata_size);
			st->codec->channels = cfg.channels;
			if (cfg.object_type == 29 && cfg.sampling_index < 3) // old mp3on4
				st->codec->sample_rate = ff_mpa_freq_tab[cfg.sampling_index];
			else if (cfg.ext_sample_rate)
				st->codec->sample_rate = cfg.ext_sample_rate;
			else
				st->codec->sample_rate = cfg.sample_rate;
			av_dlog(fc, "mp4a config channels %d obj %d ext obj %d "
			        "sample rate %d ext sample rate %d\n", st->codec->channels,
			        cfg.object_type, cfg.ext_object_type,
			        cfg.sample_rate, cfg.ext_sample_rate);
			if (!(st->codec->codec_id = ff_codec_get_id(mp4_audio_types,
			                            cfg.object_type)))
				st->codec->codec_id = CODEC_ID_AAC;
		}
	}
	return 0;
}
Ejemplo n.º 6
0
/**
 * Try to find Xing/Info/VBRI tags and compute duration from info therein
 */
static int mp3_parse_vbr_tags(AVFormatContext *s, AVStream *st, int64_t base)
{
    MP3Context *mp3 = s->priv_data;
    uint32_t v, spf;
    unsigned frames = 0; /* Total number of frames in file */
    unsigned size = 0; /* Total number of bytes in the stream */
    const int64_t xing_offtbl[2][2] = {{32, 17}, {17,9}};
    MPADecodeHeader c;
    int vbrtag_size = 0;

    v = avio_rb32(s->pb);
    if(ff_mpa_check_header(v) < 0)
      return -1;

    if (avpriv_mpegaudio_decode_header(&c, v) == 0)
        vbrtag_size = c.frame_size;
    if(c.layer != 3)
        return -1;

    /* Check for Xing / Info tag */
    avio_skip(s->pb, xing_offtbl[c.lsf == 1][c.nb_channels == 1]);
    v = avio_rb32(s->pb);
    if(v == MKBETAG('X', 'i', 'n', 'g') || v == MKBETAG('I', 'n', 'f', 'o')) {
        v = avio_rb32(s->pb);
        if(v & 0x1)
            frames = avio_rb32(s->pb);
        if(v & 0x2)
            size = avio_rb32(s->pb);
        if(v & 4)
            avio_skip(s->pb, 100);
        if(v & 8)
            avio_skip(s->pb, 4);

        v = avio_rb32(s->pb);
        if(v == MKBETAG('L', 'A', 'M', 'E') || v == MKBETAG('L', 'a', 'v', 'f')) {
            avio_skip(s->pb, 21-4);
            v= avio_rb24(s->pb);
            mp3->start_pad = v>>12;
            mp3->  end_pad = v&4095;
            st->skip_samples = mp3->start_pad + 528 + 1;
            av_log(s, AV_LOG_DEBUG, "pad %d %d\n", mp3->start_pad, mp3->  end_pad);
        }
Ejemplo n.º 7
0
static int smush_read_header(AVFormatContext *ctx)
{
    SMUSHContext *smush = ctx->priv_data;
    AVIOContext *pb = ctx->pb;
    AVStream *vst, *ast;
    uint32_t magic, nframes, size, subversion, i;
    uint32_t width = 0, height = 0, got_audio = 0, read = 0;
    uint32_t sample_rate, channels, palette[256];

    magic = avio_rb32(pb);
    avio_skip(pb, 4); // skip movie size

    if (magic == MKBETAG('A', 'N', 'I', 'M')) {
        if (avio_rb32(pb) != MKBETAG('A', 'H', 'D', 'R'))
            return AVERROR_INVALIDDATA;

        size = avio_rb32(pb);
        if (size < 3 * 256 + 6)
            return AVERROR_INVALIDDATA;

        smush->version = 0;
        subversion     = avio_rl16(pb);
        nframes        = avio_rl16(pb);
        if (!nframes)
            return AVERROR_INVALIDDATA;

        avio_skip(pb, 2); // skip pad

        for (i = 0; i < 256; i++)
            palette[i] = avio_rb24(pb);

        avio_skip(pb, size - (3 * 256 + 6));
    } else if (magic == MKBETAG('S', 'A', 'N', 'M')) {
        if (avio_rb32(pb) != MKBETAG('S', 'H', 'D', 'R'))
            return AVERROR_INVALIDDATA;

        size = avio_rb32(pb);
        if (size < 14)
            return AVERROR_INVALIDDATA;

        smush->version = 1;
        subversion = avio_rl16(pb);
        nframes = avio_rl32(pb);
        if (!nframes)
            return AVERROR_INVALIDDATA;

        avio_skip(pb, 2); // skip pad
        width  = avio_rl16(pb);
        height = avio_rl16(pb);
        avio_skip(pb, 2); // skip pad
        avio_skip(pb, size - 14);

        if (avio_rb32(pb) != MKBETAG('F', 'L', 'H', 'D'))
            return AVERROR_INVALIDDATA;

        size = avio_rb32(pb);
        while (!got_audio && ((read + 8) < size)) {
            uint32_t sig, chunk_size;

            if (avio_feof(pb))
                return AVERROR_EOF;

            sig        = avio_rb32(pb);
            chunk_size = avio_rb32(pb);
            read      += 8;
            switch (sig) {
            case MKBETAG('W', 'a', 'v', 'e'):
                got_audio = 1;
                sample_rate = avio_rl32(pb);
                if (!sample_rate)
                    return AVERROR_INVALIDDATA;

                channels = avio_rl32(pb);
                if (!channels)
                    return AVERROR_INVALIDDATA;

                avio_skip(pb, chunk_size - 8);
                read += chunk_size;
                break;
            case MKBETAG('B', 'l', '1', '6'):
            case MKBETAG('A', 'N', 'N', 'O'):
                avio_skip(pb, chunk_size);
                read += chunk_size;
                break;
            default:
                return AVERROR_INVALIDDATA;
                break;
            }
        }

        avio_skip(pb, size - read);
    } else {
        av_log(ctx, AV_LOG_ERROR, "Wrong magic\n");
        return AVERROR_INVALIDDATA;
    }

    vst = avformat_new_stream(ctx, 0);
    if (!vst)
        return AVERROR(ENOMEM);

    smush->video_stream_index = vst->index;

    avpriv_set_pts_info(vst, 64, 1, 15);

    vst->start_time        = 0;
    vst->duration          =
    vst->nb_frames         = nframes;
    vst->avg_frame_rate    = av_inv_q(vst->time_base);
    vst->codec->codec_type = AVMEDIA_TYPE_VIDEO;
    vst->codec->codec_id   = AV_CODEC_ID_SANM;
    vst->codec->codec_tag  = 0;
    vst->codec->width      = width;
    vst->codec->height     = height;

    if (!smush->version) {
        if (ff_alloc_extradata(vst->codec, 1024 + 2))
            return AVERROR(ENOMEM);

        AV_WL16(vst->codec->extradata, subversion);
        for (i = 0; i < 256; i++)
            AV_WL32(vst->codec->extradata + 2 + i * 4, palette[i]);
    }

    if (got_audio) {
        ast = avformat_new_stream(ctx, 0);
        if (!ast)
            return AVERROR(ENOMEM);

        smush->audio_stream_index = ast->index;

        ast->start_time         = 0;
        ast->codec->codec_type  = AVMEDIA_TYPE_AUDIO;
        ast->codec->codec_id    = AV_CODEC_ID_ADPCM_VIMA;
        ast->codec->codec_tag   = 0;
        ast->codec->sample_rate = sample_rate;
        ast->codec->channels    = channels;

        avpriv_set_pts_info(ast, 64, 1, ast->codec->sample_rate);
    }

    return 0;
}
Ejemplo n.º 8
0
static int tak_read_header(AVFormatContext *s)
{
    TAKDemuxContext *tc = s->priv_data;
    AVIOContext *pb     = s->pb;
    GetBitContext gb;
    AVStream *st;
    uint8_t *buffer = NULL;
    int ret;

    st = avformat_new_stream(s, 0);
    if (!st)
        return AVERROR(ENOMEM);

    st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
    st->codec->codec_id   = AV_CODEC_ID_TAK;
    st->need_parsing      = AVSTREAM_PARSE_FULL_RAW;

    tc->mlast_frame = 0;
    if (avio_rl32(pb) != MKTAG('t', 'B', 'a', 'K')) {
        avio_seek(pb, -4, SEEK_CUR);
        return 0;
    }

    while (!avio_feof(pb)) {
        enum TAKMetaDataType type;
        int size;

        type = avio_r8(pb) & 0x7f;
        size = avio_rl24(pb);

        switch (type) {
        case TAK_METADATA_STREAMINFO:
        case TAK_METADATA_LAST_FRAME:
        case TAK_METADATA_ENCODER:
            if (size <= 3)
                return AVERROR_INVALIDDATA;

            buffer = av_malloc(size - 3 + FF_INPUT_BUFFER_PADDING_SIZE);
            if (!buffer)
                return AVERROR(ENOMEM);
            memset(buffer + size - 3, 0, FF_INPUT_BUFFER_PADDING_SIZE);

            ffio_init_checksum(pb, tak_check_crc, 0xCE04B7U);
            if (avio_read(pb, buffer, size - 3) != size - 3) {
                av_freep(&buffer);
                return AVERROR(EIO);
            }
            if (ffio_get_checksum(s->pb) != avio_rb24(pb)) {
                av_log(s, AV_LOG_ERROR, "%d metadata block CRC error.\n", type);
                if (s->error_recognition & AV_EF_EXPLODE) {
                    av_freep(&buffer);
                    return AVERROR_INVALIDDATA;
                }
            }

            init_get_bits8(&gb, buffer, size - 3);
            break;
        case TAK_METADATA_MD5: {
            uint8_t md5[16];
            int i;

            if (size != 19)
                return AVERROR_INVALIDDATA;
            ffio_init_checksum(pb, tak_check_crc, 0xCE04B7U);
            avio_read(pb, md5, 16);
            if (ffio_get_checksum(s->pb) != avio_rb24(pb)) {
                av_log(s, AV_LOG_ERROR, "MD5 metadata block CRC error.\n");
                if (s->error_recognition & AV_EF_EXPLODE)
                    return AVERROR_INVALIDDATA;
            }

            av_log(s, AV_LOG_VERBOSE, "MD5=");
            for (i = 0; i < 16; i++)
                av_log(s, AV_LOG_VERBOSE, "%02x", md5[i]);
            av_log(s, AV_LOG_VERBOSE, "\n");
            break;
        }
        case TAK_METADATA_END: {
            int64_t curpos = avio_tell(pb);

            if (pb->seekable) {
                ff_ape_parse_tag(s);
                avio_seek(pb, curpos, SEEK_SET);
            }

            tc->data_end += curpos;
            return 0;
        }
        default:
            ret = avio_skip(pb, size);
            if (ret < 0)
                return ret;
        }

        if (type == TAK_METADATA_STREAMINFO) {
            TAKStreamInfo ti;

            avpriv_tak_parse_streaminfo(&gb, &ti);
            if (ti.samples > 0)
                st->duration = ti.samples;
            st->codec->bits_per_coded_sample = ti.bps;
            if (ti.ch_layout)
                st->codec->channel_layout = ti.ch_layout;
            st->codec->sample_rate           = ti.sample_rate;
            st->codec->channels              = ti.channels;
            st->start_time                   = 0;
            avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);
            st->codec->extradata             = buffer;
            st->codec->extradata_size        = size - 3;
            buffer                           = NULL;
        } else if (type == TAK_METADATA_LAST_FRAME) {
            if (size != 11)
                return AVERROR_INVALIDDATA;
            tc->mlast_frame = 1;
            tc->data_end    = get_bits64(&gb, TAK_LAST_FRAME_POS_BITS) +
                              get_bits(&gb, TAK_LAST_FRAME_SIZE_BITS);
            av_freep(&buffer);
        } else if (type == TAK_METADATA_ENCODER) {
            av_log(s, AV_LOG_VERBOSE, "encoder version: %0X\n",
                   get_bits_long(&gb, TAK_ENCODER_VERSION_BITS));
            av_freep(&buffer);
        }
    }

    return AVERROR_EOF;
}
Ejemplo n.º 9
0
/**
 * @return 0 when a packet was written into /p pkt, and no more data is left;
 *         1 when a packet was written into /p pkt, and more packets might be left;
 *        <0 when not enough data was provided to return a full packet, or on error.
 */
static int asfrtp_parse_packet(AVFormatContext *s, PayloadContext *asf,
                               AVStream *st, AVPacket *pkt,
                               uint32_t *timestamp,
                               const uint8_t *buf, int len, uint16_t seq,
                               int flags)
{
    AVIOContext *pb = &asf->pb;
    int res, mflags, len_off;
    RTSPState *rt = s->priv_data;

    if (!rt->asf_ctx)
        return -1;

    if (len > 0) {
        int off, out_len = 0;

        if (len < 4)
            return -1;

        av_freep(&asf->buf);

        ffio_init_context(pb, buf, len, 0, NULL, NULL, NULL, NULL);

        while (avio_tell(pb) + 4 < len) {
            int start_off = avio_tell(pb);

            mflags = avio_r8(pb);
            if (mflags & 0x80)
                flags |= RTP_FLAG_KEY;
            len_off = avio_rb24(pb);
            if (mflags & 0x20)   /**< relative timestamp */
                avio_skip(pb, 4);
            if (mflags & 0x10)   /**< has duration */
                avio_skip(pb, 4);
            if (mflags & 0x8)    /**< has location ID */
                avio_skip(pb, 4);
            off = avio_tell(pb);

            if (!(mflags & 0x40)) {
                /**
                 * If 0x40 is not set, the len_off field specifies an offset
                 * of this packet's payload data in the complete (reassembled)
                 * ASF packet. This is used to spread one ASF packet over
                 * multiple RTP packets.
                 */
                if (asf->pktbuf && len_off != avio_tell(asf->pktbuf)) {
                    uint8_t *p;
                    avio_close_dyn_buf(asf->pktbuf, &p);
                    asf->pktbuf = NULL;
                    av_free(p);
                }
                if (!len_off && !asf->pktbuf &&
                    (res = avio_open_dyn_buf(&asf->pktbuf)) < 0)
                    return res;
                if (!asf->pktbuf)
                    return AVERROR(EIO);

                avio_write(asf->pktbuf, buf + off, len - off);
                avio_skip(pb, len - off);
                if (!(flags & RTP_FLAG_MARKER))
                    return -1;
                out_len     = avio_close_dyn_buf(asf->pktbuf, &asf->buf);
                asf->pktbuf = NULL;
            } else {
                /**
                 * If 0x40 is set, the len_off field specifies the length of
                 * the next ASF packet that can be read from this payload
                 * data alone. This is commonly the same as the payload size,
                 * but could be less in case of packet splitting (i.e.
                 * multiple ASF packets in one RTP packet).
                 */

                int cur_len = start_off + len_off - off;
                int prev_len = out_len;
                out_len += cur_len;
                if (FFMIN(cur_len, len - off) < 0)
                    return -1;
                if ((res = av_reallocp(&asf->buf, out_len)) < 0)
                    return res;
                memcpy(asf->buf + prev_len, buf + off,
                       FFMIN(cur_len, len - off));
                avio_skip(pb, cur_len);
            }
        }

        init_packetizer(pb, asf->buf, out_len);
        pb->pos += rt->asf_pb_pos;
        pb->eof_reached = 0;
        rt->asf_ctx->pb = pb;
    }

    for (;;) {
        int i;

        res = ff_read_packet(rt->asf_ctx, pkt);
        rt->asf_pb_pos = avio_tell(pb);
        if (res != 0)
            break;
        for (i = 0; i < s->nb_streams; i++) {
            if (s->streams[i]->id == rt->asf_ctx->streams[pkt->stream_index]->id) {
                pkt->stream_index = i;
                return 1; // FIXME: return 0 if last packet
            }
        }
        av_free_packet(pkt);
    }

    return res == 1 ? -1 : res;
}
Ejemplo n.º 10
0
Archivo: pva.c Proyecto: 2BReality/xbmc
static int read_part_of_packet(AVFormatContext *s, int64_t *pts,
                               int *len, int *strid, int read_packet) {
    AVIOContext *pb = s->pb;
    PVAContext *pvactx = s->priv_data;
    int syncword, streamid, reserved, flags, length, pts_flag;
    int64_t pva_pts = AV_NOPTS_VALUE, startpos;

recover:
    startpos = avio_tell(pb);

    syncword = avio_rb16(pb);
    streamid = avio_r8(pb);
    avio_r8(pb);               /* counter not used */
    reserved = avio_r8(pb);
    flags    = avio_r8(pb);
    length   = avio_rb16(pb);

    pts_flag = flags & 0x10;

    if (syncword != PVA_MAGIC) {
        pva_log(s, AV_LOG_ERROR, "invalid syncword\n");
        return AVERROR(EIO);
    }
    if (streamid != PVA_VIDEO_PAYLOAD && streamid != PVA_AUDIO_PAYLOAD) {
        pva_log(s, AV_LOG_ERROR, "invalid streamid\n");
        return AVERROR(EIO);
    }
    if (reserved != 0x55) {
        pva_log(s, AV_LOG_WARNING, "expected reserved byte to be 0x55\n");
    }
    if (length > PVA_MAX_PAYLOAD_LENGTH) {
        pva_log(s, AV_LOG_ERROR, "invalid payload length %u\n", length);
        return AVERROR(EIO);
    }

    if (streamid == PVA_VIDEO_PAYLOAD && pts_flag) {
        pva_pts = avio_rb32(pb);
        length -= 4;
    } else if (streamid == PVA_AUDIO_PAYLOAD) {
        /* PVA Audio Packets either start with a signaled PES packet or
         * are a continuation of the previous PES packet. New PES packets
         * always start at the beginning of a PVA Packet, never somewhere in
         * the middle. */
        if (!pvactx->continue_pes) {
            int pes_signal, pes_header_data_length, pes_packet_length,
                pes_flags;
            unsigned char pes_header_data[256];

            pes_signal             = avio_rb24(pb);
            avio_r8(pb);
            pes_packet_length      = avio_rb16(pb);
            pes_flags              = avio_rb16(pb);
            pes_header_data_length = avio_r8(pb);

            if (pes_signal != 1) {
                pva_log(s, AV_LOG_WARNING, "expected signaled PES packet, "
                                          "trying to recover\n");
                avio_skip(pb, length - 9);
                if (!read_packet)
                    return AVERROR(EIO);
                goto recover;
            }

            avio_read(pb, pes_header_data, pes_header_data_length);
            length -= 9 + pes_header_data_length;

            pes_packet_length -= 3 + pes_header_data_length;

            pvactx->continue_pes = pes_packet_length;

            if (pes_flags & 0x80 && (pes_header_data[0] & 0xf0) == 0x20)
                pva_pts = ff_parse_pes_pts(pes_header_data);
        }

        pvactx->continue_pes -= length;

        if (pvactx->continue_pes < 0) {
            pva_log(s, AV_LOG_WARNING, "audio data corruption\n");
            pvactx->continue_pes = 0;
        }
    }

    if (pva_pts != AV_NOPTS_VALUE)
        av_add_index_entry(s->streams[streamid-1], startpos, pva_pts, 0, 0, AVINDEX_KEYFRAME);

    *pts   = pva_pts;
    *len   = length;
    *strid = streamid;
    return 0;
}
Ejemplo n.º 11
0
static void mp3_parse_info_tag(AVFormatContext *s, AVStream *st,
                               MPADecodeHeader *c, uint32_t spf)
{
#define LAST_BITS(k, n) ((k) & ((1 << (n)) - 1))
#define MIDDLE_BITS(k, m, n) LAST_BITS((k) >> (m), ((n) - (m)))

    uint16_t crc;
    uint32_t v;

    char version[10];

    uint32_t peak   = 0;
    int32_t  r_gain = INT32_MIN, a_gain = INT32_MIN;

    MP3DecContext *mp3 = s->priv_data;
    const int64_t xing_offtbl[2][2] = {{32, 17}, {17,9}};

    /* Check for Xing / Info tag */
    avio_skip(s->pb, xing_offtbl[c->lsf == 1][c->nb_channels == 1]);
    v = avio_rb32(s->pb);
    mp3->is_cbr = v == MKBETAG('I', 'n', 'f', 'o');
    if (v != MKBETAG('X', 'i', 'n', 'g') && !mp3->is_cbr)
        return;

    v = avio_rb32(s->pb);
    if (v & XING_FLAG_FRAMES)
        mp3->frames = avio_rb32(s->pb);
    if (v & XING_FLAG_SIZE)
        mp3->size = avio_rb32(s->pb);
    if (v & XING_FLAG_TOC && mp3->frames)
        read_xing_toc(s, mp3->size, av_rescale_q(mp3->frames,
                                       (AVRational){spf, c->sample_rate},
                                       st->time_base));

    /* VBR quality */
    if (v & XING_FLAC_QSCALE)
        avio_rb32(s->pb);

    /* Encoder short version string */
    memset(version, 0, sizeof(version));
    avio_read(s->pb, version, 9);

    /* Info Tag revision + VBR method */
    avio_r8(s->pb);

    /* Lowpass filter value */
    avio_r8(s->pb);

    /* ReplayGain peak */
    v    = avio_rb32(s->pb);
    peak = av_rescale(v, 100000, 1 << 23);

    /* Radio ReplayGain */
    v = avio_rb16(s->pb);

    if (MIDDLE_BITS(v, 13, 15) == 1) {
        r_gain = MIDDLE_BITS(v, 0, 8) * 10000;

        if (v & (1 << 9))
            r_gain *= -1;
    }

    /* Audiophile ReplayGain */
    v = avio_rb16(s->pb);

    if (MIDDLE_BITS(v, 13, 15) == 2) {
        a_gain = MIDDLE_BITS(v, 0, 8) * 10000;

        if (v & (1 << 9))
            a_gain *= -1;
    }

    /* Encoding flags + ATH Type */
    avio_r8(s->pb);

    /* if ABR {specified bitrate} else {minimal bitrate} */
    avio_r8(s->pb);

    /* Encoder delays */
    avio_rb24(s->pb);

    /* Misc */
    avio_r8(s->pb);

    /* MP3 gain */
    avio_r8(s->pb);

    /* Preset and surround info */
    avio_rb16(s->pb);

    /* Music length */
    avio_rb32(s->pb);

    /* Music CRC */
    avio_rb16(s->pb);

    /* Info Tag CRC */
    crc = ffio_get_checksum(s->pb);
    v   = avio_rb16(s->pb);

    if (v == crc) {
        ff_replaygain_export_raw(st, r_gain, peak, a_gain, 0);
        av_dict_set(&st->metadata, "encoder", version, 0);
    }
}
Ejemplo n.º 12
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;
    }