Esempio n. 1
0
static int dca_parse(AVCodecParserContext *s, AVCodecContext *avctx,
                     const uint8_t **poutbuf, int *poutbuf_size,
                     const uint8_t *buf, int buf_size)
{
    DCAParseContext *pc1 = s->priv_data;
    ParseContext *pc = &pc1->pc;
    int next, duration, sample_rate;

    if (s->flags & PARSER_FLAG_COMPLETE_FRAMES) {
        next = buf_size;
    } else {
        next = dca_find_frame_end(pc1, buf, buf_size);

        if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) {
            *poutbuf      = NULL;
            *poutbuf_size = 0;
            return buf_size;
        }
    }

    /* read the duration and sample rate from the frame header */
    if (!dca_parse_params(buf, buf_size, &duration, &sample_rate, &pc1->framesize)) {
        s->duration        = duration;
        avctx->sample_rate = sample_rate;
    } else
        s->duration = 0;

    *poutbuf      = buf;
    *poutbuf_size = buf_size;
    return next;
}
Esempio n. 2
0
static int pnm_parse(AVCodecParserContext *s,
                           AVCodecContext *avctx,
                           const uint8_t **poutbuf, int *poutbuf_size,
                           const uint8_t *buf, int buf_size)
{
    ParseContext *pc = s->priv_data;
    PNMContext pnmctx;
    int next;

    for(; pc->overread>0; pc->overread--){
        pc->buffer[pc->index++]= pc->buffer[pc->overread_index++];
    }
retry:
    if(pc->index){
        pnmctx.bytestream_start=
        pnmctx.bytestream= pc->buffer;
        pnmctx.bytestream_end= pc->buffer + pc->index;
    }else{
        pnmctx.bytestream_start=
        pnmctx.bytestream= (uint8_t *) buf; /* casts avoid warnings */
        pnmctx.bytestream_end= (uint8_t *) buf + buf_size;
    }
    if(ff_pnm_decode_header(avctx, &pnmctx) < 0){
        if(pnmctx.bytestream < pnmctx.bytestream_end){
            if(pc->index){
                pc->index=0;
            }else{
                buf++;
                buf_size--;
            }
            goto retry;
        }
#if 0
        if(pc->index && pc->index*2 + FF_INPUT_BUFFER_PADDING_SIZE < pc->buffer_size && buf_size > pc->index){
            memcpy(pc->buffer + pc->index, buf, pc->index);
            pc->index += pc->index;
            buf += pc->index;
            buf_size -= pc->index;
            goto retry;
        }
#endif
        next= END_NOT_FOUND;
    }else{
        next= pnmctx.bytestream - pnmctx.bytestream_start
            + avpicture_get_size(avctx->pix_fmt, avctx->width, avctx->height);
        if(pnmctx.bytestream_start!=buf)
            next-= pc->index;
        if(next > buf_size)
            next= END_NOT_FOUND;
    }

    if(ff_combine_frame(pc, next, &buf, &buf_size)<0){
        *poutbuf = NULL;
        *poutbuf_size = 0;
        return buf_size;
    }
    *poutbuf = buf;
    *poutbuf_size = buf_size;
    return next;
}
Esempio n. 3
0
static int mpeg4video_parse(AVCodecParserContext *s,
                           AVCodecContext *avctx,
                           const uint8_t **poutbuf, int *poutbuf_size,
                           const uint8_t *buf, int buf_size)
{
    ParseContext *pc = s->priv_data;
    int next;

    if(s->flags & PARSER_FLAG_COMPLETE_FRAMES){
        next= buf_size;
    }else{
        next= ff_mpeg4_find_frame_end(pc, buf, buf_size);

        if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) {
            *poutbuf = NULL;
            *poutbuf_size = 0;
            return buf_size;
        }
    }
    av_mpeg4_decode_header(s, avctx, buf, buf_size);

    *poutbuf = buf;
    *poutbuf_size = buf_size;
    return next;
}
Esempio n. 4
0
static int jpeg_parse(AVCodecParserContext *s,
                      AVCodecContext *avctx,
                      const uint8_t **poutbuf, int *poutbuf_size,
                      const uint8_t *buf, int buf_size)
{
    MJPEGParserContext *m = s->priv_data;
    ParseContext *pc = &m->pc;
    int next;

    if(s->flags & PARSER_FLAG_COMPLETE_FRAMES){
        next= buf_size;
    }else{
        next= find_frame_end(m, buf, buf_size);

        if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) {
            *poutbuf = NULL;
            *poutbuf_size = 0;
            return buf_size;
        }
    }

    *poutbuf = buf;
    *poutbuf_size = buf_size;
    return next;
}
Esempio n. 5
0
static int gsm_parse(AVCodecParserContext *s1, AVCodecContext *avctx,
                     const uint8_t **poutbuf, int *poutbuf_size,
                     const uint8_t *buf, int buf_size)
{
    GSMParseContext *s = s1->priv_data;
    ParseContext *pc = &s->pc;
    int next;

    if (!s->block_size) {
        switch (avctx->codec_id) {
        case AV_CODEC_ID_GSM:
            s->block_size = GSM_BLOCK_SIZE;
            s->duration   = GSM_FRAME_SIZE;
            break;
        case AV_CODEC_ID_GSM_MS:
            s->block_size = avctx->block_align ? avctx->block_align
                                               : GSM_MS_BLOCK_SIZE;
            s->duration   = GSM_FRAME_SIZE * 2;
            break;
        default:
            av_assert0(0);
        }
    }

    if (!s->remaining)
        s->remaining = s->block_size;
    if (s->remaining <= buf_size) {
        next = s->remaining;
        s->remaining = 0;
    } else {
        next = END_NOT_FOUND;
        s->remaining -= buf_size;
    }

    if (ff_combine_frame(pc, next, &buf, &buf_size) < 0 || !buf_size) {
        *poutbuf      = NULL;
        *poutbuf_size = 0;
        return buf_size;
    }

    s1->duration = s->duration;

    *poutbuf      = buf;
    *poutbuf_size = buf_size;
    return next;
}
Esempio n. 6
0
static int h261_parse(AVCodecParserContext *s,
                      AVCodecContext *avctx,
                      const uint8_t **poutbuf, int *poutbuf_size,
                      const uint8_t *buf, int buf_size)
{
    ParseContext *pc = s->priv_data;
    int next;

    next= h261_find_frame_end(pc,avctx, buf, buf_size);
    if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) {
        *poutbuf = NULL;
        *poutbuf_size = 0;
        return buf_size;
    }
    *poutbuf = buf;
    *poutbuf_size = buf_size;
    return next;
}
int ff_aac_ac3_parse(AVCodecParserContext *s1,
                     AVCodecContext *avctx,
                     const uint8_t **poutbuf, int *poutbuf_size,
                     const uint8_t *buf, int buf_size)
{
    AACAC3ParseContext *s = s1->priv_data;
    ParseContext *pc = &s->pc;
    int len, i;
    int new_frame_start;
    int got_frame = 0;

    if ((s1->flags & PARSER_FLAG_SKIP && s->parse_full) || avctx->extradata_size) {
        s->remaining_size = 0;
        s1->flags |= PARSER_FLAG_COMPLETE_FRAMES;
        s1->duration = -1;
        if (s1->flags & PARSER_FLAG_ONCE) {
            got_frame = 1;
            i = buf_size;
            goto skip_sync;
        } else {
            *poutbuf = buf;
            *poutbuf_size = buf_size;
            return buf_size;
        }
    }

get_next:
    i=END_NOT_FOUND;
    if(s->remaining_size <= buf_size){
        if(s->remaining_size && !s->need_next_header){
            i= s->remaining_size;
            s->remaining_size = 0;
        }else{ //we need a header first
            len=0;
            for(i=s->remaining_size; i<buf_size; i++){
                s->state = (s->state<<8) + buf[i];
                if((len=s->sync(s->state, s, &s->need_next_header, &new_frame_start)))
                    break;
            }
            if(len<=0){
                i=END_NOT_FOUND;
            }else{
                got_frame = 1;
                s->state=0;
                i-= s->header_size -1;
                s->remaining_size = len;
                if(!new_frame_start || pc->index+i<=0){
                    s->remaining_size += i;
                    goto get_next;
                }
            }
        }
    }

    if(ff_combine_frame(pc, i, &buf, &buf_size)<0){
        s->remaining_size -= FFMIN(s->remaining_size, buf_size);
        *poutbuf = NULL;
        *poutbuf_size = 0;
        return buf_size;
    }

skip_sync:
    *poutbuf = buf;
    *poutbuf_size = buf_size;

    /* update codec info */
    if(s->codec_id)
        avctx->codec_id = s->codec_id;

    if (s->parse_full && s1->flags & PARSER_FLAG_ONCE) {
        if (!s->parse_full(s1, avctx, buf, buf_size))
            s1->flags &= ~PARSER_FLAG_ONCE;
    }

    if (got_frame) {
        if (avctx->codec_id != AV_CODEC_ID_AAC) {
            avctx->sample_rate = s->sample_rate;
            avctx->channels = s->channels;
            avctx->channel_layout = s->channel_layout;
            s1->duration = s->samples;
            avctx->audio_service_type = s->service_type;

            avctx->sample_fmt = AV_SAMPLE_FMT_S16P;
        }

        avctx->bit_rate = s->bit_rate;
    }

    return i;
}
Esempio n. 8
0
static int tak_parse(AVCodecParserContext *s, AVCodecContext *avctx,
                     const uint8_t **poutbuf, int *poutbuf_size,
                     const uint8_t *buf, int buf_size)
{
    TAKParseContext *t = s->priv_data;
    ParseContext *pc   = &t->pc;
    int next           = END_NOT_FOUND;
    GetBitContext gb;
    int consumed = 0;
    int needed   = buf_size ? TAK_MAX_FRAME_HEADER_BYTES : 8;

    if (s->flags & PARSER_FLAG_COMPLETE_FRAMES) {
        TAKStreamInfo ti;
        init_get_bits(&gb, buf, buf_size);
        if (!ff_tak_decode_frame_header(avctx, &gb, &ti, 127))
            s->duration = t->ti.last_frame_samples ? t->ti.last_frame_samples
                                                   : t->ti.frame_samples;
        *poutbuf      = buf;
        *poutbuf_size = buf_size;
        return buf_size;
    }

    while (buf_size || t->index + needed <= pc->index) {
        if (buf_size && t->index + TAK_MAX_FRAME_HEADER_BYTES > pc->index) {
            int tmp_buf_size       = FFMIN(2 * TAK_MAX_FRAME_HEADER_BYTES,
                                           buf_size);
            const uint8_t *tmp_buf = buf;

            if (ff_combine_frame(pc, END_NOT_FOUND, &tmp_buf, &tmp_buf_size) != -1)
                return AVERROR(ENOMEM);
            consumed += tmp_buf_size;
            buf      += tmp_buf_size;
            buf_size -= tmp_buf_size;
        }

        for (; t->index + needed <= pc->index; t->index++) {
            if (pc->buffer[ t->index     ] == 0xFF &&
                pc->buffer[ t->index + 1 ] == 0xA0) {
                TAKStreamInfo ti;

                init_get_bits(&gb, pc->buffer + t->index,
                              8 * (pc->index - t->index));
                if (!ff_tak_decode_frame_header(avctx, &gb,
                        pc->frame_start_found ? &ti : &t->ti, 127) &&
                    !ff_tak_check_crc(pc->buffer + t->index,
                                      get_bits_count(&gb) / 8)) {
                    if (!pc->frame_start_found) {
                        pc->frame_start_found = 1;
                        s->duration           = t->ti.last_frame_samples ?
                                                t->ti.last_frame_samples :
                                                t->ti.frame_samples;
                        s->key_frame          = !!(t->ti.flags & TAK_FRAME_FLAG_HAS_INFO);
                    } else {
                        pc->frame_start_found = 0;
                        next                  = t->index - pc->index;
                        t->index              = 0;
                        goto found;
                    }
                }
            }
        }
    }
found:

    if (consumed && !buf_size && next == END_NOT_FOUND ||
        ff_combine_frame(pc, next, &buf, &buf_size) < 0) {
        *poutbuf      = NULL;
        *poutbuf_size = 0;
        return buf_size + consumed;
    }

    if (next != END_NOT_FOUND) {
        next        += consumed;
        pc->overread = FFMAX(0, -next);
    }

    *poutbuf      = buf;
    *poutbuf_size = buf_size;
    return next;
}
Esempio n. 9
0
int ff_aac_ac3_parse(AVCodecParserContext *s1,
                     AVCodecContext *avctx,
                     const uint8_t **poutbuf, int *poutbuf_size,
                     const uint8_t *buf, int buf_size)
{
    AACAC3ParseContext *s = s1->priv_data;
    ParseContext *pc = &s->pc;
    int len, i;
    int new_frame_start;

get_next:
    i=END_NOT_FOUND;
    if(s->remaining_size <= buf_size){
        if(s->remaining_size && !s->need_next_header){
            i= s->remaining_size;
            s->remaining_size = 0;
        }else{ //we need a header first
            len=0;
            for(i=s->remaining_size; i<buf_size; i++){
                s->state = (s->state<<8) + buf[i];
                if((len=s->sync(s->state, s, &s->need_next_header, &new_frame_start)))
                    break;
            }
            if(len<=0){
                i=END_NOT_FOUND;
            }else{
                i-= s->header_size -1;
                s->remaining_size = len;
                if(!new_frame_start){
                    s->remaining_size += i;
                    goto get_next;
                }
            }
        }
    }

    if(ff_combine_frame(pc, i, &buf, &buf_size)<0){
        s->remaining_size -= FFMIN(s->remaining_size, buf_size);
        *poutbuf = NULL;
        *poutbuf_size = 0;
        return buf_size;
    }

    *poutbuf = buf;
    *poutbuf_size = buf_size;

    /* update codec info */
    avctx->sample_rate = s->sample_rate;
    /* allow downmixing to stereo (or mono for AC3) */
    if(avctx->request_channels > 0 &&
            avctx->request_channels < s->channels &&
            (avctx->request_channels <= 2 ||
            (avctx->request_channels == 1 &&
            avctx->codec_id == CODEC_ID_AC3))) {
        avctx->channels = avctx->request_channels;
    } else {
        avctx->channels = s->channels;
    }
    avctx->bit_rate = s->bit_rate;
    avctx->frame_size = s->samples;

    return i;
}
Esempio n. 10
0
static int vc1_parse(AVCodecParserContext *s,
                           AVCodecContext *avctx,
                           const uint8_t **poutbuf, int *poutbuf_size,
                           const uint8_t *buf, int buf_size)
{
    /* Here we do the searching for frame boundaries and headers at
     * the same time. Only a minimal amount at the start of each
     * header is unescaped. */
    VC1ParseContext *vpc = s->priv_data;
    int pic_found = vpc->pc.frame_start_found;
    uint8_t *unesc_buffer = vpc->unesc_buffer;
    size_t unesc_index = vpc->unesc_index;
    VC1ParseSearchState search_state = vpc->search_state;
    int start_code_found = 0;
    int next = END_NOT_FOUND;
    int i = vpc->bytes_to_skip;

    if (pic_found && buf_size == 0) {
        /* EOF considered as end of frame */
        memset(unesc_buffer + unesc_index, 0, UNESCAPED_THRESHOLD - unesc_index);
        vc1_extract_header(s, avctx, unesc_buffer, unesc_index);
        next = 0;
    }
    while (i < buf_size) {
        uint8_t b;
        start_code_found = 0;
        while (i < buf_size && unesc_index < UNESCAPED_THRESHOLD) {
            b = buf[i++];
            unesc_buffer[unesc_index++] = b;
            if (search_state <= ONE_ZERO)
                search_state = b ? NO_MATCH : search_state + 1;
            else if (search_state == TWO_ZEROS) {
                if (b == 1)
                    search_state = ONE;
                else if (b > 1) {
                    if (b == 3)
                        unesc_index--; // swallow emulation prevention byte
                    search_state = NO_MATCH;
                }
            }
            else { // search_state == ONE
                // Header unescaping terminates early due to detection of next start code
                search_state = NO_MATCH;
                start_code_found = 1;
                break;
            }
        }
        if ((s->flags & PARSER_FLAG_COMPLETE_FRAMES) &&
                unesc_index >= UNESCAPED_THRESHOLD &&
                vpc->prev_start_code == (VC1_CODE_FRAME & 0xFF))
        {
            // No need to keep scanning the rest of the buffer for
            // start codes if we know it contains a complete frame and
            // we've already unescaped all we need of the frame header
            vc1_extract_header(s, avctx, unesc_buffer, unesc_index);
            break;
        }
        if (unesc_index >= UNESCAPED_THRESHOLD && !start_code_found) {
            while (i < buf_size) {
                if (search_state == NO_MATCH) {
                    i += ff_startcode_find_candidate_c(buf + i, buf_size - i);
                    if (i < buf_size) {
                        search_state = ONE_ZERO;
                    }
                    i++;
                } else {
                    b = buf[i++];
                    if (search_state == ONE_ZERO)
                        search_state = b ? NO_MATCH : TWO_ZEROS;
                    else if (search_state == TWO_ZEROS) {
                        if (b >= 1)
                            search_state = b == 1 ? ONE : NO_MATCH;
                    }
                    else { // search_state == ONE
                        search_state = NO_MATCH;
                        start_code_found = 1;
                        break;
                    }
                }
            }
        }
        if (start_code_found) {
            vc1_extract_header(s, avctx, unesc_buffer, unesc_index);

            vpc->prev_start_code = b;
            unesc_index = 0;

            if (!(s->flags & PARSER_FLAG_COMPLETE_FRAMES)) {
                if (!pic_found && (b == (VC1_CODE_FRAME & 0xFF) || b == (VC1_CODE_FIELD & 0xFF))) {
                    pic_found = 1;
                }
                else if (pic_found && b != (VC1_CODE_FIELD & 0xFF) && b != (VC1_CODE_SLICE & 0xFF)) {
                    next = i - 4;
                    pic_found = b == (VC1_CODE_FRAME & 0xFF);
                    break;
                }
            }
        }
    }

    vpc->pc.frame_start_found = pic_found;
    vpc->unesc_index = unesc_index;
    vpc->search_state = search_state;

    if (s->flags & PARSER_FLAG_COMPLETE_FRAMES) {
        next = buf_size;
    } else {
        if (ff_combine_frame(&vpc->pc, next, &buf, &buf_size) < 0) {
            vpc->bytes_to_skip = 0;
            *poutbuf = NULL;
            *poutbuf_size = 0;
            return buf_size;
        }
    }

    /* If we return with a valid pointer to a combined frame buffer
     * then on the next call then we'll have been unhelpfully rewound
     * by up to 4 bytes (depending upon whether the start code
     * overlapped the input buffer, and if so by how much). We don't
     * want this: it will either cause spurious second detections of
     * the start code we've already seen, or cause extra bytes to be
     * inserted at the start of the unescaped buffer. */
    vpc->bytes_to_skip = 4;
    if (next < 0 && next != END_NOT_FOUND)
        vpc->bytes_to_skip += next;

    *poutbuf = buf;
    *poutbuf_size = buf_size;
    return next;
}
Esempio n. 11
0
static int mpegaudio_parse(AVCodecParserContext *s1,
                           AVCodecContext *avctx,
                           const uint8_t **poutbuf, int *poutbuf_size,
                           const uint8_t *buf, int buf_size)
{
    MpegAudioParseContext *s = s1->priv_data;
    ParseContext *pc = &s->pc;
    uint32_t state= pc->state;
    int i;
    int next= END_NOT_FOUND;
    int flush = !buf_size;

    for(i=0; i<buf_size; ){
        if(s->frame_size){
            int inc= FFMIN(buf_size - i, s->frame_size);
            i += inc;
            s->frame_size -= inc;
            state = 0;

            if(!s->frame_size){
                next= i;
                break;
            }
        }else{
            while(i<buf_size){
                int ret, sr, channels, bit_rate, frame_size;
                enum AVCodecID codec_id = avctx->codec_id;

                state= (state<<8) + buf[i++];

                ret = ff_mpa_decode_header(state, &sr, &channels, &frame_size, &bit_rate, &codec_id);
                if (ret < 4) {
                    if (i > 4)
                        s->header_count = -2;
                } else {
                    int header_threshold = avctx->codec_id != AV_CODEC_ID_NONE && avctx->codec_id != codec_id;
                    if((state&SAME_HEADER_MASK) != (s->header&SAME_HEADER_MASK) && s->header)
                        s->header_count= -3;
                    s->header= state;
                    s->header_count++;
                    s->frame_size = ret-4;

                    if (s->header_count > header_threshold) {
                        avctx->sample_rate= sr;
                        avctx->channels   = channels;
                        s1->duration      = frame_size;
                        avctx->codec_id   = codec_id;
                        if (s->no_bitrate || !avctx->bit_rate) {
                            s->no_bitrate = 1;
                            avctx->bit_rate += (bit_rate - avctx->bit_rate) / (s->header_count - header_threshold);
                        }
                    }

                    if (s1->flags & PARSER_FLAG_COMPLETE_FRAMES) {
                        s->frame_size = 0;
                        next = buf_size;
                    } else if (codec_id == AV_CODEC_ID_MP3ADU) {
                        avpriv_report_missing_feature(avctx,
                            "MP3ADU full parser");
                        *poutbuf = NULL;
                        *poutbuf_size = 0;
                        return buf_size; /* parsers must not return error codes */
                    }

                    break;
                }
            }
        }
    }

    pc->state= state;
    if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) {
        *poutbuf = NULL;
        *poutbuf_size = 0;
        return buf_size;
    }

    if (flush && buf_size >= ID3v1_TAG_SIZE && memcmp(buf, "TAG", 3) == 0) {
        *poutbuf = NULL;
        *poutbuf_size = 0;
        return next;
    }

    if (flush && buf_size >= APE_TAG_FOOTER_BYTES && memcmp(buf, APE_TAG_PREAMBLE, 8) == 0) {
        *poutbuf = NULL;
        *poutbuf_size = 0;
        return next;
    }

    *poutbuf = buf;
    *poutbuf_size = buf_size;
    return next;
}
int ff_aac_ac3_parse(AVCodecParserContext *s1,
                     AVCodecContext *avctx,
                     const uint8_t **poutbuf, int *poutbuf_size,
                     const uint8_t *buf, int buf_size)
{
	AACAC3ParseContext *s = s1->priv_data;
	ParseContext *pc = &s->pc;
	int len, i;
	int new_frame_start;

get_next:
	i=END_NOT_FOUND;
	if(s->remaining_size <= buf_size)
	{
		if(s->remaining_size && !s->need_next_header)
		{
			i= s->remaining_size;
			s->remaining_size = 0;
		}
		else   //we need a header first
		{
			len=0;
			for(i=s->remaining_size; i<buf_size; i++)
			{
				s->state = (s->state<<8) + buf[i];
				if((len=s->sync(s->state, s, &s->need_next_header, &new_frame_start)))
					break;
			}
			if(len<=0)
			{
				i=END_NOT_FOUND;
			}
			else
			{
				s->state=0;
				i-= s->header_size -1;
				s->remaining_size = len;
				if(!new_frame_start || pc->index+i<=0)
				{
					s->remaining_size += i;
					goto get_next;
				}
			}
		}
	}

	if(ff_combine_frame(pc, i, &buf, &buf_size)<0)
	{
		s->remaining_size -= FFMIN(s->remaining_size, buf_size);
		*poutbuf = NULL;
		*poutbuf_size = 0;
		return buf_size;
	}

	*poutbuf = buf;
	*poutbuf_size = buf_size;

	/* update codec info */
	if(s->codec_id)
		avctx->codec_id = s->codec_id;

	/* Due to backwards compatible HE-AAC the sample rate, channel count,
	   and total number of samples found in an AAC ADTS header are not
	   reliable. Bit rate is still accurate because the total frame duration in
	   seconds is still correct (as is the number of bits in the frame). */
	if (avctx->codec_id != CODEC_ID_AAC)
	{
		avctx->sample_rate = s->sample_rate;

		/* allow downmixing to stereo (or mono for AC-3) */
		if(avctx->request_channels > 0 &&
		        avctx->request_channels < s->channels &&
		        (avctx->request_channels <= 2 ||
		         (avctx->request_channels == 1 &&
		          (avctx->codec_id == CODEC_ID_AC3 ||
		           avctx->codec_id == CODEC_ID_EAC3))))
		{
			avctx->channels = avctx->request_channels;
		}
		else
		{
			avctx->channels = s->channels;
			avctx->channel_layout = s->channel_layout;
		}
		avctx->frame_size = s->samples;
		avctx->audio_service_type = s->service_type;
	}

	avctx->bit_rate = s->bit_rate;

	return i;
}
Esempio n. 13
0
static int pnm_parse(AVCodecParserContext *s, AVCodecContext *avctx,
                     const uint8_t **poutbuf, int *poutbuf_size,
                     const uint8_t *buf, int buf_size)
{
    PNMParseContext *pnmpc = s->priv_data;
    ParseContext *pc = &pnmpc->pc;
    PNMContext pnmctx;
    int next = END_NOT_FOUND;
    int skip = 0;

    for (; pc->overread > 0; pc->overread--) {
        pc->buffer[pc->index++]= pc->buffer[pc->overread_index++];
    }

    if (pnmpc->remaining_bytes) {
        int inc = FFMIN(pnmpc->remaining_bytes, buf_size);
        skip += inc;
        pnmpc->remaining_bytes -= inc;

        if (!pnmpc->remaining_bytes)
            next = skip;
        goto end;
    }

retry:
    if (pc->index) {
        pnmctx.bytestream_start =
        pnmctx.bytestream       = pc->buffer;
        pnmctx.bytestream_end   = pc->buffer + pc->index;
    } else {
        pnmctx.bytestream_start =
        pnmctx.bytestream       = (uint8_t *) buf + skip; /* casts avoid warnings */
        pnmctx.bytestream_end   = (uint8_t *) buf + buf_size - skip;
    }
    if (ff_pnm_decode_header(avctx, &pnmctx) < 0) {
        if (pnmctx.bytestream < pnmctx.bytestream_end) {
            if (pc->index) {
                pc->index = 0;
                pnmpc->ascii_scan = 0;
            } else {
                unsigned step = FFMAX(1, pnmctx.bytestream - pnmctx.bytestream_start);

                skip += step;
            }
            goto retry;
        }
    } else if (pnmctx.type < 4) {
              uint8_t *bs  = pnmctx.bytestream;
        const uint8_t *end = pnmctx.bytestream_end;
        uint8_t *sync      = bs;

        if (pc->index) {
            av_assert0(pnmpc->ascii_scan <= end - bs);
            bs += pnmpc->ascii_scan;
        }

        while (bs < end) {
            int c;
            sync = bs;
            c = *bs++;
            if (c == '#')  {
                while (c != '\n' && bs < end)
                    c = *bs++;
            } else if (c == 'P') {
                next = bs - pnmctx.bytestream_start + skip - 1;
                pnmpc->ascii_scan = 0;
                break;
            }
        }
        if (next == END_NOT_FOUND)
            pnmpc->ascii_scan = sync - pnmctx.bytestream + skip;
    } else {
        next = pnmctx.bytestream - pnmctx.bytestream_start + skip
               + av_image_get_buffer_size(avctx->pix_fmt, avctx->width, avctx->height, 1);
    }
    if (next != END_NOT_FOUND && pnmctx.bytestream_start != buf + skip)
        next -= pc->index;
    if (next > buf_size) {
        pnmpc->remaining_bytes = next - buf_size;
        next = END_NOT_FOUND;
    }
end:
    if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) {
        *poutbuf      = NULL;
        *poutbuf_size = 0;
        return buf_size;
    }
    *poutbuf      = buf;
    *poutbuf_size = buf_size;
    return next;
}
Esempio n. 14
0
static int png_parse(AVCodecParserContext *s, AVCodecContext *avctx,
                     const uint8_t **poutbuf, int *poutbuf_size,
                     const uint8_t *buf, int buf_size)
{
    PNGParseContext *ppc = s->priv_data;
    int next = END_NOT_FOUND;
    int i = 0;

    *poutbuf_size = 0;
    if (buf_size == 0)
        return 0;

    if (!ppc->pc.frame_start_found) {
        uint64_t state64 = ppc->pc.state64;
        for (; i < buf_size; i++) {
            state64 = (state64 << 8) | buf[i];
            if (state64 == PNG_SIGNATURE ||
                state64 == MNG_SIGNATURE) {
                i++;
                ppc->pc.frame_start_found = 1;
                break;
            }
        }
        ppc->pc.state64 = state64;
    } else if (ppc->remaining_size) {
        i = FFMIN(ppc->remaining_size, buf_size);
        ppc->remaining_size -= i;
        if (ppc->remaining_size)
            goto flush;
        if (ppc->chunk_pos == -1) {
            next = i;
            goto flush;
        }
    }

    for (; ppc->pc.frame_start_found && i < buf_size; i++) {
        ppc->pc.state = (ppc->pc.state << 8) | buf[i];
        if (ppc->chunk_pos == 3) {
            ppc->chunk_length = ppc->pc.state;
            if (ppc->chunk_length > 0x7fffffff) {
                ppc->chunk_pos = ppc->pc.frame_start_found = 0;
                goto flush;
            }
            ppc->chunk_length += 4;
        } else if (ppc->chunk_pos == 7) {
            if (ppc->chunk_length >= buf_size - i)
                ppc->remaining_size = ppc->chunk_length - buf_size + i + 1;
            if (ppc->pc.state == MKBETAG('I', 'E', 'N', 'D')) {
                if (ppc->remaining_size)
                    ppc->chunk_pos = -1;
                else
                    next = ppc->chunk_length + i + 1;
                break;
            } else {
                ppc->chunk_pos = 0;
                if (ppc->remaining_size)
                    break;
                else
                    i += ppc->chunk_length;
                continue;
            }
        }
        ppc->chunk_pos++;
    }

flush:
    if (ff_combine_frame(&ppc->pc, next, &buf, &buf_size) < 0)
        return buf_size;

    ppc->chunk_pos = ppc->pc.frame_start_found = 0;

    *poutbuf      = buf;
    *poutbuf_size = buf_size;
    return next;
}
Esempio n. 15
0
static int mpegaudio_parse(AVCodecParserContext *s1,
                           AVCodecContext *avctx,
                           const uint8_t **poutbuf, int *poutbuf_size,
                           const uint8_t *buf, int buf_size)
{
    MpegAudioParseContext *s = s1->priv_data;
    ParseContext *pc = &s->pc;
    uint32_t state= pc->state;
    int i;
    int next= END_NOT_FOUND;
    int sr = 0, channels = 0, bit_rate = 0, frame_size = 0;

    for(i=0; i<buf_size; ){
        if(s->frame_size){
            int inc= FFMIN(buf_size - i, s->frame_size);
            i += inc;
            s->frame_size -= inc;

            if(!s->frame_size){
                next= i;
                break;
            }
        }else{
            while(i<buf_size){
                int ret;

                state= (state<<8) + buf[i++];

                ret = ff_mpa_decode_header(avctx, state, &sr, &channels, &frame_size, &bit_rate);
                if (ret < 4) {
                    if(i > 4)
                        s->header_count= -2;
                } else {
                    if((state&SAME_HEADER_MASK) != (s->header&SAME_HEADER_MASK) && s->header)
                        s->header_count= -3;
                    s->header= state;
                    s->header_count++;
                    s->frame_size = ret-4;
                    break;
                }
            }
        }
    }

    pc->state= state;
    if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) {
        *poutbuf = NULL;
        *poutbuf_size = 0;
        return buf_size;
    }

    state = AV_RB32(buf);
    if (ff_mpa_decode_header(avctx, state, &sr, &channels, &frame_size, &bit_rate) < 0) {
        *poutbuf = NULL;
        *poutbuf_size = 0;
        return next;
    }

    avctx->sample_rate= sr;
    avctx->channels   = channels;
    avctx->frame_size = frame_size;
    avctx->bit_rate   = bit_rate;

    *poutbuf = buf;
    *poutbuf_size = buf_size;
    return next;
}
Esempio n. 16
0
static int mpegaudio_parse(AVCodecParserContext *s1,
                           AVCodecContext *avctx,
                           const uint8_t **poutbuf, int *poutbuf_size,
                           const uint8_t *buf, int buf_size)
{
    MpegAudioParseContext *s = s1->priv_data;
    ParseContext *pc = &s->pc;
    uint32_t state= pc->state;
    int i;
    int next= END_NOT_FOUND;

    for(i=0; i<buf_size; ){
        if(s->frame_size){
            int inc= FFMIN(buf_size - i, s->frame_size);
            i += inc;
            s->frame_size -= inc;
            state = 0;

            if(!s->frame_size){
                next= i;
                break;
            }
        }else{
            while(i<buf_size){
                int ret, sr, channels, bit_rate, frame_size;
                enum AVCodecID codec_id;

                state= (state<<8) + buf[i++];

                ret = avpriv_mpa_decode_header2(state, &sr, &channels, &frame_size, &bit_rate, &codec_id);
                if (ret < 4) {
                    if (i > 4)
                        s->header_count = -2;
                } else {
                    if((state&SAME_HEADER_MASK) != (s->header&SAME_HEADER_MASK) && s->header)
                        s->header_count= -3;
                    s->header= state;
                    s->header_count++;
                    s->frame_size = ret-4;

                    if (s->header_count > 0 + (avctx->codec_id != AV_CODEC_ID_NONE && avctx->codec_id != codec_id)) {
                        avctx->sample_rate= sr;
                        avctx->channels   = channels;
                        s1->duration      = frame_size;
                        avctx->codec_id   = codec_id;
                        if (s->no_bitrate || !avctx->bit_rate) {
                            s->no_bitrate = 1;
                            avctx->bit_rate += (bit_rate - avctx->bit_rate) / s->header_count;
                        }
                    }
                    break;
                }
            }
        }
    }

    pc->state= state;
    if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) {
        *poutbuf = NULL;
        *poutbuf_size = 0;
        return buf_size;
    }

    *poutbuf = buf;
    *poutbuf_size = buf_size;
    return next;
}
Esempio n. 17
0
static int dpx_parse(AVCodecParserContext *s, AVCodecContext *avctx,
                     const uint8_t **poutbuf, int *poutbuf_size,
                     const uint8_t *buf, int buf_size)
{
    DPXParseContext *d = s->priv_data;
    uint32_t state = d->pc.state;
    int next = END_NOT_FOUND;
    int i = 0;

    s->pict_type = AV_PICTURE_TYPE_I;

    *poutbuf_size = 0;
    if (buf_size == 0)
        next = 0;

    if (!d->pc.frame_start_found) {
        for (; i < buf_size; i++) {
            state = (state << 8) | buf[i];
            if (state == MKBETAG('S','D','P','X') ||
                state == MKTAG('S','D','P','X')) {
                d->pc.frame_start_found = 1;
                d->is_be = state == MKBETAG('S','D','P','X');
                d->index = 0;
                break;
            }
        }
        d->pc.state = state;
    } else {
        if (d->remaining_size) {
            i = FFMIN(d->remaining_size, buf_size);
            d->remaining_size -= i;
            if (d->remaining_size)
                goto flush;
        }
    }

    for (; d->pc.frame_start_found && i < buf_size; i++) {
        d->pc.state = (d->pc.state << 8) | buf[i];
        d->index++;
        if (d->index == 17) {
            d->fsize = d->is_be ? d->pc.state : av_bswap32(d->pc.state);
            if (d->fsize <= 1664) {
                d->pc.frame_start_found = 0;
                goto flush;
            }
            if (d->fsize > buf_size - i + 19)
                d->remaining_size = d->fsize - buf_size + i - 19;
            else
                i += d->fsize - 19;

            break;
        } else if (d->index > 17) {
            if (d->pc.state == MKBETAG('S','D','P','X') ||
                d->pc.state == MKTAG('S','D','P','X')) {
                next = i - 3;
                break;
            }
        }
    }

flush:
    if (ff_combine_frame(&d->pc, next, &buf, &buf_size) < 0)
        return buf_size;

    d->pc.frame_start_found = 0;

    *poutbuf      = buf;
    *poutbuf_size = buf_size;
    return next;
}
Esempio n. 18
0
int ff_aac_ac3_parse(AVCodecParserContext *s1,
                     AVCodecContext *avctx,
                     const uint8_t **poutbuf, int *poutbuf_size,
                     const uint8_t *buf, int buf_size)
{
    AACAC3ParseContext *s = s1->priv_data;
    ParseContext *pc = &s->pc;
    int len, i;
    int new_frame_start;

get_next:
    i=END_NOT_FOUND;
    if(s->remaining_size <= buf_size){
        if(s->remaining_size && !s->need_next_header){
            i= s->remaining_size;
            s->remaining_size = 0;
        }else{ //we need a header first
            len=0;
            for(i=s->remaining_size; i<buf_size; i++){
                s->state = (s->state<<8) + buf[i];
                if((len=s->sync(s->state, s, &s->need_next_header, &new_frame_start)))
                    break;
            }
            if(len<=0){
                i=END_NOT_FOUND;
            }else{
                s->state=0;
                i-= s->header_size -1;
                s->remaining_size = len;
                if(!new_frame_start || pc->index+i<=0){
                    s->remaining_size += i;
                    goto get_next;
                }
            }
        }
    }

    if(ff_combine_frame(pc, i, &buf, &buf_size)<0){
        s->remaining_size -= FFMIN(s->remaining_size, buf_size);
        *poutbuf = NULL;
        *poutbuf_size = 0;
        return buf_size;
    }

    *poutbuf = buf;
    *poutbuf_size = buf_size;

    /* update codec info */
    if(s->codec_id)
        avctx->codec_id = s->codec_id;

    /* Due to backwards compatible HE-AAC the sample rate, channel count,
       and total number of samples found in an AAC ADTS header are not
       reliable. Bit rate is still accurate because the total frame duration in
       seconds is still correct (as is the number of bits in the frame). */
    if (avctx->codec_id != AV_CODEC_ID_AAC) {
        avctx->sample_rate = s->sample_rate;

        /* (E-)AC-3: allow downmixing to stereo or mono */
#if FF_API_REQUEST_CHANNELS
FF_DISABLE_DEPRECATION_WARNINGS
        if (avctx->request_channels == 1)
            avctx->request_channel_layout = AV_CH_LAYOUT_MONO;
        else if (avctx->request_channels == 2)
            avctx->request_channel_layout = AV_CH_LAYOUT_STEREO;
FF_ENABLE_DEPRECATION_WARNINGS
#endif
        if (s->channels > 1 &&
            avctx->request_channel_layout == AV_CH_LAYOUT_MONO) {
            avctx->channels       = 1;
            avctx->channel_layout = AV_CH_LAYOUT_MONO;
        } else if (s->channels > 2 &&
                   avctx->request_channel_layout == AV_CH_LAYOUT_STEREO) {
            avctx->channels       = 2;
            avctx->channel_layout = AV_CH_LAYOUT_STEREO;
        } else {
            avctx->channels = s->channels;
            avctx->channel_layout = s->channel_layout;
        }
        s1->duration = s->samples;
        avctx->audio_service_type = s->service_type;
    }