?? asf.c
字號(hào):
header_size = cur_pos - header_offset; if (asf->is_streamed) { header_size += 8 + 30 + 50; url_fseek(pb, header_offset - 10 - 30, SEEK_SET); put_le16(pb, header_size); url_fseek(pb, header_offset - 2 - 30, SEEK_SET); put_le16(pb, header_size); header_size -= 8 + 30 + 50; } header_size += 24 + 6; url_fseek(pb, header_offset - 14, SEEK_SET); put_le64(pb, header_size); url_fseek(pb, cur_pos, SEEK_SET); /* movie chunk, followed by packets of packet_size */ asf->data_offset = cur_pos; put_guid(pb, &data_header); put_le64(pb, data_chunk_size); put_guid(pb, &my_guid); put_le64(pb, asf->nb_packets); /* nb packets */ put_byte(pb, 1); /* ??? */ put_byte(pb, 1); /* ??? */ return 0;}static int asf_write_header(AVFormatContext *s){ ASFContext *asf = s->priv_data; av_set_pts_info(s, 32, 1, 1000); /* 32 bit pts in ms */ asf->packet_size = PACKET_SIZE; asf->nb_packets = 0; if (asf_write_header1(s, 0, 50) < 0) { //av_free(asf); return -1; } put_flush_packet(&s->pb); asf->packet_nb_frames = 0; asf->packet_timestamp_start = -1; asf->packet_timestamp_end = -1; asf->packet_size_left = asf->packet_size - PACKET_HEADER_SIZE; init_put_byte(&asf->pb, asf->packet_buf, asf->packet_size, 1, NULL, NULL, NULL, NULL); return 0;}static int asf_write_stream_header(AVFormatContext *s){ ASFContext *asf = s->priv_data; asf->is_streamed = 1; return asf_write_header(s);}/* write a fixed size packet */static int put_packet(AVFormatContext *s, unsigned int timestamp, unsigned int duration, int nb_frames, int padsize){ ASFContext *asf = s->priv_data; ByteIOContext *pb = &s->pb; int flags; if (asf->is_streamed) { put_chunk(s, 0x4424, asf->packet_size, 0); } put_byte(pb, 0x82); put_le16(pb, 0); flags = 0x01; /* nb segments present */ if (padsize > 0) { if (padsize < 256) flags |= 0x08; else flags |= 0x10; } put_byte(pb, flags); /* flags */ put_byte(pb, 0x5d); if (flags & 0x10) put_le16(pb, padsize - 2); if (flags & 0x08) put_byte(pb, padsize - 1); put_le32(pb, timestamp); put_le16(pb, duration); put_byte(pb, nb_frames | 0x80); return PACKET_HEADER_SIZE + ((flags & 0x18) >> 3);}static void flush_packet(AVFormatContext *s){ ASFContext *asf = s->priv_data; int hdr_size, ptr; hdr_size = put_packet(s, asf->packet_timestamp_start, asf->packet_timestamp_end - asf->packet_timestamp_start, asf->packet_nb_frames, asf->packet_size_left); /* Clear out the padding bytes */ ptr = asf->packet_size - hdr_size - asf->packet_size_left; memset(asf->packet_buf + ptr, 0, asf->packet_size_left); put_buffer(&s->pb, asf->packet_buf, asf->packet_size - hdr_size); put_flush_packet(&s->pb); asf->nb_packets++; asf->packet_nb_frames = 0; asf->packet_timestamp_start = -1; asf->packet_timestamp_end = -1; asf->packet_size_left = asf->packet_size - PACKET_HEADER_SIZE; init_put_byte(&asf->pb, asf->packet_buf, asf->packet_size, 1, NULL, NULL, NULL, NULL);}static void put_frame_header(AVFormatContext *s, ASFStream *stream, int timestamp, int payload_size, int frag_offset, int frag_len){ ASFContext *asf = s->priv_data; ByteIOContext *pb = &asf->pb; int val; val = stream->num; if (s->streams[val - 1]->codec.coded_frame->key_frame /* && frag_offset == 0 */) val |= 0x80; put_byte(pb, val); put_byte(pb, stream->seq); put_le32(pb, frag_offset); /* fragment offset */ put_byte(pb, 0x08); /* flags */ put_le32(pb, payload_size); put_le32(pb, timestamp); put_le16(pb, frag_len);}/* Output a frame. We suppose that payload_size <= PACKET_SIZE. It is there that you understand that the ASF format is really crap. They have misread the MPEG Systems spec ! */static void put_frame(AVFormatContext *s, ASFStream *stream, int timestamp, const uint8_t *buf, int payload_size){ ASFContext *asf = s->priv_data; int frag_pos, frag_len, frag_len1; frag_pos = 0; while (frag_pos < payload_size) { frag_len = payload_size - frag_pos; frag_len1 = asf->packet_size_left - FRAME_HEADER_SIZE; if (frag_len1 > 0) { if (frag_len > frag_len1) frag_len = frag_len1; put_frame_header(s, stream, timestamp+1, payload_size, frag_pos, frag_len); put_buffer(&asf->pb, buf, frag_len); asf->packet_size_left -= (frag_len + FRAME_HEADER_SIZE); asf->packet_timestamp_end = timestamp; if (asf->packet_timestamp_start == -1) asf->packet_timestamp_start = timestamp; asf->packet_nb_frames++; } else { frag_len = 0; } frag_pos += frag_len; buf += frag_len; /* output the frame if filled */ if (asf->packet_size_left <= FRAME_HEADER_SIZE) flush_packet(s); } stream->seq++;}static int asf_write_packet(AVFormatContext *s, int stream_index, const uint8_t *buf, int size, int64_t timestamp){ ASFContext *asf = s->priv_data; ASFStream *stream; int64_t duration; AVCodecContext *codec; codec = &s->streams[stream_index]->codec; stream = &asf->streams[stream_index]; if (codec->codec_type == CODEC_TYPE_AUDIO) { duration = (codec->frame_number * codec->frame_size * int64_t_C(10000000)) / codec->sample_rate; } else { duration = av_rescale(codec->frame_number * codec->frame_rate_base, 10000000, codec->frame_rate); } if (duration > asf->duration) asf->duration = duration; put_frame(s, stream, timestamp, buf, size); return 0;}static int asf_write_trailer(AVFormatContext *s){ ASFContext *asf = s->priv_data; int64_t file_size; /* flush the current packet */ if (asf->pb.buf_ptr > asf->pb.buffer) flush_packet(s); if (asf->is_streamed) { put_chunk(s, 0x4524, 0, 0); /* end of stream */ } else { /* rewrite an updated header */ file_size = url_ftell(&s->pb); url_fseek(&s->pb, 0, SEEK_SET); asf_write_header1(s, file_size, file_size - asf->data_offset); } put_flush_packet(&s->pb); return 0;}#endif //CONFIG_ENCODERS/**********************************//* decoding *///#define DEBUG#ifdef DEBUG#define PRINT_IF_GUID(g,cmp) \if (!memcmp(g, &cmp, sizeof(GUID))) \ printf("(GUID: %s) ", #cmp)static void print_guid(const GUID *g){ int i; PRINT_IF_GUID(g, asf_header); else PRINT_IF_GUID(g, file_header); else PRINT_IF_GUID(g, stream_header); else PRINT_IF_GUID(g, audio_stream); else PRINT_IF_GUID(g, audio_conceal_none); else PRINT_IF_GUID(g, video_stream); else PRINT_IF_GUID(g, video_conceal_none); else PRINT_IF_GUID(g, comment_header); else PRINT_IF_GUID(g, codec_comment_header); else PRINT_IF_GUID(g, codec_comment1_header); else PRINT_IF_GUID(g, data_header); else PRINT_IF_GUID(g, index_guid); else PRINT_IF_GUID(g, head1_guid); else PRINT_IF_GUID(g, head2_guid); else PRINT_IF_GUID(g, my_guid); else printf("(GUID: unknown) "); printf("0x%08x, 0x%04x, 0x%04x, {", g->v1, g->v2, g->v3); for(i=0;i<8;i++) printf(" 0x%02x,", g->v4[i]); printf("}\n");}#undef PRINT_IF_GUID(g,cmp)#endifstatic void get_guid(ByteIOContext *s, GUID *g){ int i; g->v1 = get_le32(s); g->v2 = get_le16(s); g->v3 = get_le16(s); for(i=0;i<8;i++) g->v4[i] = get_byte(s);}#if 0static void get_str16(ByteIOContext *pb, char *buf, int buf_size){ int len, c; char *q; len = get_le16(pb); q = buf; while (len > 0) { c = get_le16(pb); if ((q - buf) < buf_size - 1) *q++ = c; len--; } *q = '\0';}#endifstatic void get_str16_nolen(ByteIOContext *pb, int len, char *buf, int buf_size){ int c; char *q; q = buf; while (len > 0) { c = get_le16(pb); if ((q - buf) < buf_size - 1) *q++ = c; len-=2; } *q = '\0';}static int asf_probe(AVProbeData *pd){ GUID g; const unsigned char *p; int i; /* check file header */ if (pd->buf_size <= 32) return 0; p = pd->buf; g.v1 = p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24); p += 4; g.v2 = p[0] | (p[1] << 8); p += 2; g.v3 = p[0] | (p[1] << 8); p += 2; for(i=0;i<8;i++) g.v4[i] = *p++; if (!memcmp(&g, &asf_header, sizeof(GUID))) return AVPROBE_SCORE_MAX; else return 0;}static int asf_read_header(AVFormatContext *s, AVFormatParameters *ap){ ASFContext *asf = s->priv_data; GUID g; ByteIOContext *pb = &s->pb; AVStream *st; ASFStream *asf_st; int size, i; int64_t gsize; av_set_pts_info(s, 32, 1, 1000); /* 32 bit pts in ms */ get_guid(pb, &g); if (memcmp(&g, &asf_header, sizeof(GUID))) goto fail; get_le64(pb); get_le32(pb); get_byte(pb); get_byte(pb); memset(&asf->asfid2avid, -1, sizeof(asf->asfid2avid)); for(;;) { get_guid(pb, &g); gsize = get_le64(pb);#ifdef DEBUG printf("%08Lx: ", url_ftell(pb) - 24); print_guid(&g); printf(" size=0x%Lx\n", gsize);#endif if (gsize < 24) goto fail; if (!memcmp(&g, &file_header, sizeof(GUID))) { get_guid(pb, &asf->hdr.guid); asf->hdr.file_size = get_le64(pb); asf->hdr.create_time = get_le64(pb); asf->hdr.packets_count = get_le64(pb); asf->hdr.play_time = get_le64(pb); asf->hdr.send_time = get_le64(pb); asf->hdr.preroll = get_le32(pb); asf->hdr.ignore = get_le32(pb); asf->hdr.flags = get_le32(pb); asf->hdr.min_pktsize = get_le32(pb); asf->hdr.max_pktsize = get_le32(pb); asf->hdr.max_bitrate = get_le32(pb); asf->packet_size = asf->hdr.max_pktsize; asf->nb_packets = asf->hdr.packets_count; } else if (!memcmp(&g, &stream_header, sizeof(GUID))) { int type, total_size, type_specific_size; unsigned int tag1; int64_t pos1, pos2; pos1 = url_ftell(pb); st = av_new_stream(s, 0); if (!st) goto fail; asf_st = av_mallocz(sizeof(ASFStream)); if (!asf_st) goto fail; st->priv_data = asf_st; st->start_time = asf->hdr.preroll / (10000000 / AV_TIME_BASE); st->duration = (asf->hdr.send_time - asf->hdr.preroll) / (10000000 / AV_TIME_BASE); get_guid(pb, &g); if (!memcmp(&g, &audio_stream, sizeof(GUID))) { type = CODEC_TYPE_AUDIO; } else if (!memcmp(&g, &video_stream, sizeof(GUID))) { type = CODEC_TYPE_VIDEO; } else { goto fail; } get_guid(pb, &g); total_size = get_le64(pb); type_specific_size = get_le32(pb); get_le32(pb); st->id = get_le16(pb) & 0x7f; /* stream id */ // mapping of asf ID to AV stream ID; asf->asfid2avid[st->id] = s->nb_streams - 1; get_le32(pb); st->codec.codec_type = type; st->codec.frame_rate = 15 * s->pts_den / s->pts_num; // 15 fps default if (type == CODEC_TYPE_AUDIO) { get_wav_header(pb, &st->codec, type_specific_size); /* We have to init the frame size at some point .... */ pos2 = url_ftell(pb); if (gsize > (pos2 + 8 - pos1 + 24)) { asf_st->ds_span = get_byte(pb); asf_st->ds_packet_size = get_le16(pb); asf_st->ds_chunk_size = get_le16(pb); asf_st->ds_data_size = get_le16(pb); asf_st->ds_silence_data = get_byte(pb); } //printf("Descrambling: ps:%d cs:%d ds:%d s:%d sd:%d\n", // asf_st->ds_packet_size, asf_st->ds_chunk_size, // asf_st->ds_data_size, asf_st->ds_span, asf_st->ds_silence_data); if (asf_st->ds_span > 1) { if (!asf_st->ds_chunk_size || (asf_st->ds_packet_size/asf_st->ds_chunk_size <= 1)) asf_st->ds_span = 0; // disable descrambling } switch (st->codec.codec_id) { case CODEC_ID_MP3: st->codec.frame_size = MPA_FRAME_SIZE;
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -