📄 rm.c
字号:
put_be32(pb, 0); put_be32(pb, 0); } put_flush_packet(pb); return 0;}#endif //CONFIG_ENCODERS/***************************************************/static void get_str(ByteIOContext *pb, char *buf, int buf_size){ int len, i; char *q; len = get_be16(pb); q = buf; for(i=0;i<len;i++) { if (i < buf_size - 1) *q++ = get_byte(pb); } *q = '\0';}static void get_str8(ByteIOContext *pb, char *buf, int buf_size){ int len, i; char *q; len = get_byte(pb); q = buf; for(i=0;i<len;i++) { if (i < buf_size - 1) *q++ = get_byte(pb); } *q = '\0';}static void rm_read_audio_stream_info(AVFormatContext *s, AVStream *st, int read_all){ ByteIOContext *pb = &s->pb; char buf[128]; uint32_t version; int i; /* ra type header */ version = get_be32(pb); /* version */ if (((version >> 16) & 0xff) == 3) { /* very old version */ for(i = 0; i < 14; i++) get_byte(pb); get_str8(pb, s->title, sizeof(s->title)); get_str8(pb, s->author, sizeof(s->author)); get_str8(pb, s->copyright, sizeof(s->copyright)); get_str8(pb, s->comment, sizeof(s->comment)); get_byte(pb); get_str8(pb, buf, sizeof(buf)); st->codec.sample_rate = 8000; st->codec.channels = 1; st->codec.codec_type = CODEC_TYPE_AUDIO; st->codec.codec_id = CODEC_ID_RA_144; } else { /* old version (4) */ get_be32(pb); /* .ra4 */ get_be32(pb); get_be16(pb); get_be32(pb); /* header size */ get_be16(pb); /* add codec info */ get_be32(pb); /* coded frame size */ get_be32(pb); /* ??? */ get_be32(pb); /* ??? */ get_be32(pb); /* ??? */ get_be16(pb); /* 1 */ get_be16(pb); /* coded frame size */ get_be32(pb); st->codec.sample_rate = get_be16(pb); get_be32(pb); st->codec.channels = get_be16(pb); get_str8(pb, buf, sizeof(buf)); /* desc */ get_str8(pb, buf, sizeof(buf)); /* desc */ st->codec.codec_type = CODEC_TYPE_AUDIO; if (!strcmp(buf, "dnet")) { st->codec.codec_id = CODEC_ID_AC3; } else { st->codec.codec_id = CODEC_ID_NONE; pstrcpy(st->codec.codec_name, sizeof(st->codec.codec_name), buf); } if (read_all) { get_byte(pb); get_byte(pb); get_byte(pb); get_str8(pb, s->title, sizeof(s->title)); get_str8(pb, s->author, sizeof(s->author)); get_str8(pb, s->copyright, sizeof(s->copyright)); get_str8(pb, s->comment, sizeof(s->comment)); } }}static int rm_read_header_old(AVFormatContext *s, AVFormatParameters *ap){ RMContext *rm = s->priv_data; AVStream *st; rm->old_format = 1; st = av_new_stream(s, 0); if (!st) goto fail; rm_read_audio_stream_info(s, st, 1); return 0; fail: return -1;}static int rm_read_header(AVFormatContext *s, AVFormatParameters *ap){ RMContext *rm = s->priv_data; AVStream *st; ByteIOContext *pb = &s->pb; unsigned int tag, v; int tag_size, size, codec_data_size, i; int64_t codec_pos; unsigned int h263_hack_version, start_time, duration; char buf[128]; int flags = 0; tag = get_le32(pb); if (tag == MKTAG('.', 'r', 'a', 0xfd)) { /* very old .ra format */ return rm_read_header_old(s, ap); } else if (tag != MKTAG('.', 'R', 'M', 'F')) { return AVERROR_IO; } get_be32(pb); /* header size */ get_be16(pb); get_be32(pb); get_be32(pb); /* number of headers */ for(;;) { if (url_feof(pb)) goto fail; tag = get_le32(pb); tag_size = get_be32(pb); get_be16(pb);#if 0 printf("tag=%c%c%c%c (%08x) size=%d\n", (tag) & 0xff, (tag >> 8) & 0xff, (tag >> 16) & 0xff, (tag >> 24) & 0xff, tag, tag_size);#endif if (tag_size < 10) goto fail; switch(tag) { case MKTAG('P', 'R', 'O', 'P'): /* file header */ get_be32(pb); /* max bit rate */ get_be32(pb); /* avg bit rate */ get_be32(pb); /* max packet size */ get_be32(pb); /* avg packet size */ get_be32(pb); /* nb packets */ get_be32(pb); /* duration */ get_be32(pb); /* preroll */ get_be32(pb); /* index offset */ get_be32(pb); /* data offset */ get_be16(pb); /* nb streams */ flags = get_be16(pb); /* flags */ break; case MKTAG('C', 'O', 'N', 'T'): get_str(pb, s->title, sizeof(s->title)); get_str(pb, s->author, sizeof(s->author)); get_str(pb, s->copyright, sizeof(s->copyright)); get_str(pb, s->comment, sizeof(s->comment)); break; case MKTAG('M', 'D', 'P', 'R'): st = av_new_stream(s, 0); if (!st) goto fail; st->id = get_be16(pb); get_be32(pb); /* max bit rate */ st->codec.bit_rate = get_be32(pb); /* bit rate */ get_be32(pb); /* max packet size */ get_be32(pb); /* avg packet size */ start_time = get_be32(pb); /* start time */ get_be32(pb); /* preroll */ duration = get_be32(pb); /* duration */ st->start_time = start_time * (AV_TIME_BASE / 1000); st->duration = duration * (AV_TIME_BASE / 1000); get_str8(pb, buf, sizeof(buf)); /* desc */ get_str8(pb, buf, sizeof(buf)); /* mimetype */ codec_data_size = get_be32(pb); codec_pos = url_ftell(pb); v = get_be32(pb); if (v == MKTAG(0xfd, 'a', 'r', '.')) { /* ra type header */ rm_read_audio_stream_info(s, st, 0); } else { if (get_le32(pb) != MKTAG('V', 'I', 'D', 'O')) { fail1: av_log(&st->codec, AV_LOG_ERROR, "Unsupported video codec\n"); goto fail; } st->codec.codec_tag = get_le32(pb); if (st->codec.codec_tag != MKTAG('R', 'V', '1', '0')) goto fail1; st->codec.width = get_be16(pb); st->codec.height = get_be16(pb); st->codec.frame_rate_base= 1; st->codec.frame_rate = get_be16(pb) * st->codec.frame_rate_base; st->codec.codec_type = CODEC_TYPE_VIDEO; get_be32(pb); get_be16(pb); get_be32(pb); get_be16(pb); /* modification of h263 codec version (!) */ h263_hack_version = get_be32(pb); switch(h263_hack_version) { case 0x10000000: case 0x10003000: case 0x10003001: st->codec.sub_id = h263_hack_version; st->codec.codec_id = CODEC_ID_RV10; break; default: /* not handled */ st->codec.codec_id = CODEC_ID_NONE; break; } } /* skip codec info */ size = url_ftell(pb) - codec_pos; url_fskip(pb, codec_data_size - size); break; case MKTAG('D', 'A', 'T', 'A'): goto header_end; default: /* unknown tag: skip it */ url_fskip(pb, tag_size - 10); break; } } header_end: rm->nb_packets = get_be32(pb); /* number of packets */ if (!rm->nb_packets && (flags & 4)) rm->nb_packets = 3600 * 25; get_be32(pb); /* next data header */ return 0; fail: for(i=0;i<s->nb_streams;i++) { av_free(s->streams[i]); } return AVERROR_IO;}static int get_num(ByteIOContext *pb, int *len){ int n, n1; n = get_be16(pb); (*len)-=2; if (n >= 0x4000) { return n - 0x4000; } else { n1 = get_be16(pb); (*len)-=2; return (n << 16) | n1; }}/* multiple of 20 bytes for ra144 (ugly) */#define RAW_PACKET_SIZE 1000static int rm_read_packet(AVFormatContext *s, AVPacket *pkt){ RMContext *rm = s->priv_data; ByteIOContext *pb = &s->pb; AVStream *st; int len, num, timestamp, i, tmp, j; uint8_t *ptr; int flags; if (rm->old_format) { /* just read raw bytes */ len = RAW_PACKET_SIZE; av_new_packet(pkt, len); pkt->stream_index = 0; len = get_buffer(pb, pkt->data, len); if (len <= 0) { av_free_packet(pkt); return AVERROR_IO; } pkt->size = len; st = s->streams[0]; } else { redo: if (rm->nb_packets == 0) return AVERROR_IO; get_be16(pb); len = get_be16(pb); if (len < 12) return AVERROR_IO; num = get_be16(pb); timestamp = get_be32(pb); get_byte(pb); /* reserved */ flags = get_byte(pb); /* flags */ rm->nb_packets--; len -= 12; st = NULL; for(i=0;i<s->nb_streams;i++) { st = s->streams[i]; if (num == st->id) break; } if (i == s->nb_streams) { /* skip packet if unknown number */ url_fskip(pb, len); goto redo; } if (st->codec.codec_type == CODEC_TYPE_VIDEO) { int full_frame, h, pic_num; h= get_byte(pb); if ((h & 0xc0) == 0xc0) { int len2, pos; full_frame = 1; len2= get_num(pb, &len); pos = get_num(pb, &len); //printf("pos:%d\n",len); len -= 2; } else { int seq, frame_size, pos; full_frame = 0; seq = get_byte(pb); frame_size = get_num(pb, &len); pos = get_num(pb, &len); //printf("seq:%d, size:%d, pos:%d\n",seq,frame_size,pos); len -= 3; } /* picture number */ pic_num= get_byte(pb); //XXX/FIXME/HACK, demuxer should be fixed to send complete frames ... if(st->codec.slice_offset==NULL) st->codec.slice_offset= (int*)av_malloc(sizeof(int)); st->codec.slice_count= full_frame; st->codec.slice_offset[0]= 0; } av_new_packet(pkt, len); pkt->stream_index = i; get_buffer(pb, pkt->data, len); } /* for AC3, needs to swap bytes */ if (st->codec.codec_id == CODEC_ID_AC3) { ptr = pkt->data; for(j=0;j<len;j+=2) { tmp = ptr[0]; ptr[0] = ptr[1]; ptr[1] = tmp; ptr += 2; } } return 0;}static int rm_read_close(AVFormatContext *s){ return 0;}static int rm_probe(AVProbeData *p){ /* check file header */ if (p->buf_size <= 32) return 0; if ((p->buf[0] == '.' && p->buf[1] == 'R' && p->buf[2] == 'M' && p->buf[3] == 'F' && p->buf[4] == 0 && p->buf[5] == 0) || (p->buf[0] == '.' && p->buf[1] == 'r' && p->buf[2] == 'a' && p->buf[3] == 0xfd)) return AVPROBE_SCORE_MAX; else return 0;}static AVInputFormat rm_iformat = { "rm", "rm format", sizeof(RMContext), rm_probe, rm_read_header, rm_read_packet, rm_read_close,};#ifdef CONFIG_ENCODERSstatic AVOutputFormat rm_oformat = { "rm", "rm format", "application/vnd.rn-realmedia", "rm,ra", sizeof(RMContext), CODEC_ID_AC3, CODEC_ID_RV10, rm_write_header, rm_write_packet, rm_write_trailer,};#endif //CONFIG_ENCODERSint rm_init(void){ av_register_input_format(&rm_iformat);#ifdef CONFIG_ENCODERS av_register_output_format(&rm_oformat);#endif //CONFIG_ENCODERS return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -