⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 asf.c

📁 F:图像处理资料264264书籍ffmpeg-0.4.9-pre1VideoStream.rar 一个视频解压缩源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	}        av_free(st);    }    return -1;}#define DO_2BITS(bits, var, defval) \    switch (bits & 3) \    { \    case 3: var = get_le32(pb); rsize += 4; break; \    case 2: var = get_le16(pb); rsize += 2; break; \    case 1: var = get_byte(pb); rsize++; break; \    default: var = defval; break; \    }static int asf_get_packet(AVFormatContext *s){    ASFContext *asf = s->priv_data;    ByteIOContext *pb = &s->pb;    uint32_t packet_length, padsize;    int rsize = 9;    int c;        if((url_ftell(&s->pb) - s->data_offset) % asf->packet_size)        return -1;    assert((url_ftell(&s->pb) - s->data_offset) % asf->packet_size == 0);        c = get_byte(pb);    if (c != 0x82) {        if (!url_feof(pb))	    av_log(s, AV_LOG_ERROR, "ff asf bad header %x  at:%lld\n", c, url_ftell(pb));    }    if ((c & 0x0f) == 2) { // always true for now	if (get_le16(pb) != 0) {            if (!url_feof(pb))		av_log(s, AV_LOG_ERROR, "ff asf bad non zero\n");	    return AVERROR_IO;	}        rsize+=2;/*    }else{        if (!url_feof(pb))	    printf("ff asf bad header %x  at:%lld\n", c, url_ftell(pb));	return AVERROR_IO;*/    }    asf->packet_flags = get_byte(pb);    asf->packet_property = get_byte(pb);    DO_2BITS(asf->packet_flags >> 5, packet_length, asf->packet_size);    DO_2BITS(asf->packet_flags >> 1, padsize, 0); // sequence ignored    DO_2BITS(asf->packet_flags >> 3, padsize, 0); // padding length    asf->packet_timestamp = get_le32(pb);    get_le16(pb); /* duration */    // rsize has at least 11 bytes which have to be present    if (asf->packet_flags & 0x01) {	asf->packet_segsizetype = get_byte(pb); rsize++;        asf->packet_segments = asf->packet_segsizetype & 0x3f;    } else {	asf->packet_segments = 1;        asf->packet_segsizetype = 0x80;    }    asf->packet_size_left = packet_length - padsize - rsize;    if (packet_length < asf->hdr.min_pktsize)        padsize += asf->hdr.min_pktsize - packet_length;    asf->packet_padsize = padsize;#ifdef DEBUG    printf("packet: size=%d padsize=%d  left=%d\n", asf->packet_size, asf->packet_padsize, asf->packet_size_left);#endif    return 0;}static int asf_read_packet(AVFormatContext *s, AVPacket *pkt){    ASFContext *asf = s->priv_data;    ASFStream *asf_st = 0;    ByteIOContext *pb = &s->pb;    //static int pc = 0;    for (;;) {	int rsize = 0;	if (asf->packet_size_left < FRAME_HEADER_SIZE	    || asf->packet_segments < 1) {	    //asf->packet_size_left <= asf->packet_padsize) {	    int ret = asf->packet_size_left + asf->packet_padsize;	    //printf("PacketLeftSize:%d  Pad:%d Pos:%Ld\n", asf->packet_size_left, asf->packet_padsize, url_ftell(pb));	    /* fail safe */	    url_fskip(pb, ret);            asf->packet_pos= url_ftell(&s->pb);	    ret = asf_get_packet(s);	    //printf("READ ASF PACKET  %d   r:%d   c:%d\n", ret, asf->packet_size_left, pc++);	    if (ret < 0 || url_feof(pb))		return AVERROR_IO;            asf->packet_time_start = 0;            continue;	}	if (asf->packet_time_start == 0) {	    /* read frame header */            int num = get_byte(pb);	    asf->packet_segments--;	    rsize++;	    asf->packet_key_frame = (num & 0x80) >> 7;	    asf->stream_index = asf->asfid2avid[num & 0x7f];	    // sequence should be ignored!	    DO_2BITS(asf->packet_property >> 4, asf->packet_seq, 0);	    DO_2BITS(asf->packet_property >> 2, asf->packet_frag_offset, 0);	    DO_2BITS(asf->packet_property, asf->packet_replic_size, 0);//printf("key:%d stream:%d seq:%d offset:%d replic_size:%d\n", asf->packet_key_frame, asf->stream_index, asf->packet_seq, //asf->packet_frag_offset, asf->packet_replic_size);	    if (asf->packet_replic_size > 1) {                assert(asf->packet_replic_size >= 8);                // it should be always at least 8 bytes - FIXME validate		asf->packet_obj_size = get_le32(pb);		asf->packet_frag_timestamp = get_le32(pb); // timestamp		if (asf->packet_replic_size > 8)		    url_fskip(pb, asf->packet_replic_size - 8);		rsize += asf->packet_replic_size; // FIXME - check validity	    } else if (asf->packet_replic_size==1){		// multipacket - frag_offset is begining timestamp		asf->packet_time_start = asf->packet_frag_offset;                asf->packet_frag_offset = 0;		asf->packet_frag_timestamp = asf->packet_timestamp;                asf->packet_time_delta = get_byte(pb);		rsize++;	    }else{                assert(asf->packet_replic_size==0);            }	    if (asf->packet_flags & 0x01) {		DO_2BITS(asf->packet_segsizetype >> 6, asf->packet_frag_size, 0); // 0 is illegal#undef DO_2BITS		//printf("Fragsize %d\n", asf->packet_frag_size);	    } else {		asf->packet_frag_size = asf->packet_size_left - rsize;		//printf("Using rest  %d %d %d\n", asf->packet_frag_size, asf->packet_size_left, rsize);	    }	    if (asf->packet_replic_size == 1) {		asf->packet_multi_size = asf->packet_frag_size;		if (asf->packet_multi_size > asf->packet_size_left) {		    asf->packet_segments = 0;                    continue;		}	    }	    asf->packet_size_left -= rsize;	    //printf("___objsize____  %d   %d    rs:%d\n", asf->packet_obj_size, asf->packet_frag_offset, rsize);	    if (asf->stream_index < 0) {                asf->packet_time_start = 0;		/* unhandled packet (should not happen) */		url_fskip(pb, asf->packet_frag_size);		asf->packet_size_left -= asf->packet_frag_size;		av_log(s, AV_LOG_ERROR, "ff asf skip %d  %d\n", asf->packet_frag_size, num & 0x7f);                continue;	    }	    asf->asf_st = s->streams[asf->stream_index]->priv_data;	}	asf_st = asf->asf_st;	if ((asf->packet_frag_offset != asf_st->frag_offset	     || (asf->packet_frag_offset		 && asf->packet_seq != asf_st->seq)) // seq should be ignored	   ) {	    /* cannot continue current packet: free it */	    // FIXME better check if packet was already allocated	    av_log(s, AV_LOG_INFO, "ff asf parser skips: %d - %d     o:%d - %d    %d %d   fl:%d\n",		   asf_st->pkt.size,		   asf->packet_obj_size,		   asf->packet_frag_offset, asf_st->frag_offset,		   asf->packet_seq, asf_st->seq, asf->packet_frag_size);	    if (asf_st->pkt.size)		av_free_packet(&asf_st->pkt);	    asf_st->frag_offset = 0;	    if (asf->packet_frag_offset != 0) {		url_fskip(pb, asf->packet_frag_size);		av_log(s, AV_LOG_INFO, "ff asf parser skiping %db\n", asf->packet_frag_size);		asf->packet_size_left -= asf->packet_frag_size;		continue;	    }	}	if (asf->packet_replic_size == 1) {	    // frag_offset is here used as the begining timestamp	    asf->packet_frag_timestamp = asf->packet_time_start;	    asf->packet_time_start += asf->packet_time_delta;	    asf->packet_obj_size = asf->packet_frag_size = get_byte(pb);	    asf->packet_size_left--;            asf->packet_multi_size--;	    if (asf->packet_multi_size < asf->packet_obj_size)	    {		asf->packet_time_start = 0;		url_fskip(pb, asf->packet_multi_size);		asf->packet_size_left -= asf->packet_multi_size;                continue;	    }	    asf->packet_multi_size -= asf->packet_obj_size;	    //printf("COMPRESS size  %d  %d  %d   ms:%d\n", asf->packet_obj_size, asf->packet_frag_timestamp, asf->packet_size_left, asf->packet_multi_size);	}	if (asf_st->frag_offset == 0) {	    /* new packet */	    av_new_packet(&asf_st->pkt, asf->packet_obj_size);	    asf_st->seq = asf->packet_seq;	    asf_st->pkt.pts = asf->packet_frag_timestamp - asf->hdr.preroll;	    asf_st->pkt.stream_index = asf->stream_index;            asf_st->packet_pos= asf->packet_pos;            //printf("new packet: stream:%d key:%d packet_key:%d audio:%d size:%d\n", //asf->stream_index, asf->packet_key_frame, asf_st->pkt.flags & PKT_FLAG_KEY,//s->streams[asf->stream_index]->codec.codec_type == CODEC_TYPE_AUDIO, asf->packet_obj_size);	    if (s->streams[asf->stream_index]->codec.codec_type == CODEC_TYPE_AUDIO) 		asf->packet_key_frame = 1;	    if (asf->packet_key_frame)		asf_st->pkt.flags |= PKT_FLAG_KEY;	}	/* read data */	//printf("READ PACKET s:%d  os:%d  o:%d,%d  l:%d   DATA:%p\n",	//       asf->packet_size, asf_st->pkt.size, asf->packet_frag_offset,	//       asf_st->frag_offset, asf->packet_frag_size, asf_st->pkt.data);	asf->packet_size_left -= asf->packet_frag_size;	if (asf->packet_size_left < 0)            continue;	get_buffer(pb, asf_st->pkt.data + asf->packet_frag_offset,		   asf->packet_frag_size);	asf_st->frag_offset += asf->packet_frag_size;	/* test if whole packet is read */	if (asf_st->frag_offset == asf_st->pkt.size) {	    /* return packet */	    if (asf_st->ds_span > 1) {		/* packet descrambling */		char* newdata = av_malloc(asf_st->pkt.size);		if (newdata) {		    int offset = 0;		    while (offset < asf_st->pkt.size) {			int off = offset / asf_st->ds_chunk_size;			int row = off / asf_st->ds_span;			int col = off % asf_st->ds_span;			int idx = row + col * asf_st->ds_packet_size / asf_st->ds_chunk_size;			//printf("off:%d  row:%d  col:%d  idx:%d\n", off, row, col, idx);			memcpy(newdata + offset,			       asf_st->pkt.data + idx * asf_st->ds_chunk_size,			       asf_st->ds_chunk_size);			offset += asf_st->ds_chunk_size;		    }		    av_free(asf_st->pkt.data);		    asf_st->pkt.data = newdata;		}	    }	    asf_st->frag_offset = 0;	    memcpy(pkt, &asf_st->pkt, sizeof(AVPacket));	    //printf("packet %d %d\n", asf_st->pkt.size, asf->packet_frag_size);	    asf_st->pkt.size = 0;	    asf_st->pkt.data = 0;	    break; // packet completed	}    }    return 0;}static int asf_read_close(AVFormatContext *s){    int i;    for(i=0;i<s->nb_streams;i++) {	AVStream *st = s->streams[i];	av_free(st->priv_data);	av_free(st->codec.extradata);    av_free(st->codec.palctrl);    }    return 0;}// Added to support seeking after packets have been read// If information is not reset, read_packet fails due to// leftover information from previous readsstatic void asf_reset_header(AVFormatContext *s){    ASFContext *asf = s->priv_data;    ASFStream *asf_st;    int i;    asf->packet_nb_frames = 0;    asf->packet_timestamp_start = -1;    asf->packet_timestamp_end = -1;    asf->packet_size_left = 0;    asf->packet_segments = 0;    asf->packet_flags = 0;    asf->packet_property = 0;    asf->packet_timestamp = 0;    asf->packet_segsizetype = 0;    asf->packet_segments = 0;    asf->packet_seq = 0;    asf->packet_replic_size = 0;    asf->packet_key_frame = 0;    asf->packet_padsize = 0;    asf->packet_frag_offset = 0;    asf->packet_frag_size = 0;    asf->packet_frag_timestamp = 0;    asf->packet_multi_size = 0;    asf->packet_obj_size = 0;    asf->packet_time_delta = 0;    asf->packet_time_start = 0;        for(i=0; i<s->nb_streams; i++){        asf_st= s->streams[i]->priv_data;        av_free_packet(&asf_st->pkt);        asf_st->frag_offset=0;        asf_st->seq=0;    }    asf->asf_st= NULL;}static int64_t asf_read_pts(AVFormatContext *s, int stream_index, int64_t *ppos, int64_t pos_limit){    ASFContext *asf = s->priv_data;    AVPacket pkt1, *pkt = &pkt1;    ASFStream *asf_st;    int64_t pts;    int64_t pos= *ppos;    int i;    int64_t start_pos[s->nb_streams];        for(i=0; i<s->nb_streams; i++){        start_pos[i]= pos;    }        pos= (pos+asf->packet_size-1-s->data_offset)/asf->packet_size*asf->packet_size+ s->data_offset;    *ppos= pos;    url_fseek(&s->pb, pos, SEEK_SET);    //printf("asf_read_pts\n");    asf_reset_header(s);    for(;;){        if (av_read_frame(s, pkt) < 0){            av_log(s, AV_LOG_INFO, "seek failed\n");    	    return AV_NOPTS_VALUE;        }                pts= pkt->pts * 1000 / AV_TIME_BASE;        av_free_packet(pkt);        if(pkt->flags&PKT_FLAG_KEY){            i= pkt->stream_index;            asf_st= s->streams[i]->priv_data;            assert((asf_st->packet_pos - s->data_offset) % asf->packet_size == 0);            pos= asf_st->packet_pos;            av_add_index_entry(s->streams[i], pos, pts, pos - start_pos[i] + 1, AVINDEX_KEYFRAME);            start_pos[i]= asf_st->packet_pos + 1;                        if(pkt->stream_index == stream_index)               break;        }    }    *ppos= pos;//printf("found keyframe at %Ld stream %d stamp:%Ld\n", *ppos, stream_index, pts);    return pts;}static int asf_read_seek(AVFormatContext *s, int stream_index, int64_t pts){    ASFContext *asf = s->priv_data;        if (asf->packet_size <= 0)        return -1;    if(av_seek_frame_binary(s, stream_index, pts)<0)        return -1;    asf_reset_header(s);    return 0;}static AVInputFormat asf_iformat = {    "asf",    "asf format",    sizeof(ASFContext),    asf_probe,    asf_read_header,    asf_read_packet,    asf_read_close,    asf_read_seek,    asf_read_pts,};#ifdef CONFIG_ENCODERS    extern AVOutputFormat asf_oformat;    extern AVOutputFormat asf_stream_oformat;#endif //CONFIG_ENCODERSint asf_init(void){    av_register_input_format(&asf_iformat);#ifdef CONFIG_ENCODERS    av_register_output_format(&asf_oformat);    av_register_output_format(&asf_stream_oformat);#endif //CONFIG_ENCODERS    return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -