/* first is true if we read the frame header */ static int ffm_read_data(AVFormatContext *s, uint8_t *buf, int size, int header) { FFMContext *ffm = s->priv_data; AVIOContext *pb = s->pb; int len, fill_size, size1, frame_offset, id; int64_t last_pos = -1; size1 = size; while (size > 0) { redo: len = ffm->packet_end - ffm->packet_ptr; if (len < 0) return -1; if (len > size) len = size; if (len == 0) { if (avio_tell(pb) == ffm->file_size) avio_seek(pb, ffm->packet_size, SEEK_SET); retry_read: if (pb->buffer_size != ffm->packet_size) { int64_t tell = avio_tell(pb); ffio_set_buf_size(pb, ffm->packet_size); avio_seek(pb, tell, SEEK_SET); } id = avio_rb16(pb); /* PACKET_ID */ if (id != PACKET_ID) { if (ffm_resync(s, id) < 0) return -1; last_pos = avio_tell(pb); } fill_size = avio_rb16(pb); ffm->dts = avio_rb64(pb); frame_offset = avio_rb16(pb); avio_read(pb, ffm->packet, ffm->packet_size - FFM_HEADER_SIZE); ffm->packet_end = ffm->packet + (ffm->packet_size - FFM_HEADER_SIZE - fill_size); if (ffm->packet_end < ffm->packet || frame_offset < 0) return -1; /* if first packet or resynchronization packet, we must handle it specifically */ if (ffm->first_packet || (frame_offset & 0x8000)) { if (!frame_offset) { /* This packet has no frame headers in it */ if (avio_tell(pb) >= ffm->packet_size * 3LL) { int64_t seekback = FFMIN(ffm->packet_size * 2LL, avio_tell(pb) - last_pos); seekback = FFMAX(seekback, 0); avio_seek(pb, -seekback, SEEK_CUR); goto retry_read; } /* This is bad, we cannot find a valid frame header */ return 0; } ffm->first_packet = 0; if ((frame_offset & 0x7fff) < FFM_HEADER_SIZE) return -1; ffm->packet_ptr = ffm->packet + (frame_offset & 0x7fff) - FFM_HEADER_SIZE; if (!header) break; } else { ffm->packet_ptr = ffm->packet; } goto redo; } memcpy(buf, ffm->packet_ptr, len); buf += len; ffm->packet_ptr += len; size -= len; header = 0; } return size1 - size; }
static int flv_write_header(AVFormatContext *s) { AVIOContext *pb = s->pb; FLVContext *flv = s->priv_data; AVCodecContext *audio_enc = NULL, *video_enc = NULL; int i, metadata_count = 0; double framerate = 0.0; int64_t metadata_size_pos, data_size, metadata_count_pos; AVDictionaryEntry *tag = NULL; for(i=0; i<s->nb_streams; i++){ AVCodecContext *enc = s->streams[i]->codec; FLVStreamContext *sc; if (enc->codec_type == AVMEDIA_TYPE_VIDEO) { if (s->streams[i]->r_frame_rate.den && s->streams[i]->r_frame_rate.num) { framerate = av_q2d(s->streams[i]->r_frame_rate); } else { framerate = 1/av_q2d(s->streams[i]->codec->time_base); } video_enc = enc; if(enc->codec_tag == 0) { av_log(enc, AV_LOG_ERROR, "video codec not compatible with flv\n"); return -1; } } else { audio_enc = enc; if(get_audio_flags(enc)<0) return -1; } avpriv_set_pts_info(s->streams[i], 32, 1, 1000); /* 32 bit pts in ms */ sc = av_mallocz(sizeof(FLVStreamContext)); if (!sc) return AVERROR(ENOMEM); s->streams[i]->priv_data = sc; sc->last_ts = -1; } flv->delay = AV_NOPTS_VALUE; avio_write(pb, "FLV", 3); avio_w8(pb,1); avio_w8(pb, FLV_HEADER_FLAG_HASAUDIO * !!audio_enc + FLV_HEADER_FLAG_HASVIDEO * !!video_enc); avio_wb32(pb,9); avio_wb32(pb,0); for(i=0; i<s->nb_streams; i++){ if(s->streams[i]->codec->codec_tag == 5){ avio_w8(pb,8); // message type avio_wb24(pb,0); // include flags avio_wb24(pb,0); // time stamp avio_wb32(pb,0); // reserved avio_wb32(pb,11); // size flv->reserved=5; } } /* write meta_tag */ avio_w8(pb, 18); // tag type META metadata_size_pos= avio_tell(pb); avio_wb24(pb, 0); // size of data part (sum of all parts below) avio_wb24(pb, 0); // time stamp avio_wb32(pb, 0); // reserved /* now data of data_size size */ /* first event name as a string */ avio_w8(pb, AMF_DATA_TYPE_STRING); put_amf_string(pb, "onMetaData"); // 12 bytes /* mixed array (hash) with size and string/type/data tuples */ avio_w8(pb, AMF_DATA_TYPE_MIXEDARRAY); metadata_count_pos = avio_tell(pb); metadata_count = 5*!!video_enc + 5*!!audio_enc + 2; // +2 for duration and file size avio_wb32(pb, metadata_count); put_amf_string(pb, "duration"); flv->duration_offset= avio_tell(pb); put_amf_double(pb, s->duration / AV_TIME_BASE); // fill in the guessed duration, it'll be corrected later if incorrect if(video_enc){ put_amf_string(pb, "width"); put_amf_double(pb, video_enc->width); put_amf_string(pb, "height"); put_amf_double(pb, video_enc->height); put_amf_string(pb, "videodatarate"); put_amf_double(pb, video_enc->bit_rate / 1024.0); put_amf_string(pb, "framerate"); put_amf_double(pb, framerate); put_amf_string(pb, "videocodecid"); put_amf_double(pb, video_enc->codec_tag); } if(audio_enc){ put_amf_string(pb, "audiodatarate"); put_amf_double(pb, audio_enc->bit_rate / 1024.0); put_amf_string(pb, "audiosamplerate"); put_amf_double(pb, audio_enc->sample_rate); put_amf_string(pb, "audiosamplesize"); put_amf_double(pb, audio_enc->codec_id == CODEC_ID_PCM_U8 ? 8 : 16); put_amf_string(pb, "stereo"); put_amf_bool(pb, audio_enc->channels == 2); put_amf_string(pb, "audiocodecid"); put_amf_double(pb, audio_enc->codec_tag); } while ((tag = av_dict_get(s->metadata, "", tag, AV_DICT_IGNORE_SUFFIX))) { put_amf_string(pb, tag->key); avio_w8(pb, AMF_DATA_TYPE_STRING); put_amf_string(pb, tag->value); metadata_count++; } put_amf_string(pb, "filesize"); flv->filesize_offset= avio_tell(pb); put_amf_double(pb, 0); // delayed write put_amf_string(pb, ""); avio_w8(pb, AMF_END_OF_OBJECT); /* write total size of tag */ data_size= avio_tell(pb) - metadata_size_pos - 10; avio_seek(pb, metadata_count_pos, SEEK_SET); avio_wb32(pb, metadata_count); avio_seek(pb, metadata_size_pos, SEEK_SET); avio_wb24(pb, data_size); avio_skip(pb, data_size + 10 - 3); avio_wb32(pb, data_size + 11); for (i = 0; i < s->nb_streams; i++) { AVCodecContext *enc = s->streams[i]->codec; if (enc->codec_id == CODEC_ID_AAC || enc->codec_id == CODEC_ID_H264) { int64_t pos; avio_w8(pb, enc->codec_type == AVMEDIA_TYPE_VIDEO ? FLV_TAG_TYPE_VIDEO : FLV_TAG_TYPE_AUDIO); avio_wb24(pb, 0); // size patched later avio_wb24(pb, 0); // ts avio_w8(pb, 0); // ts ext avio_wb24(pb, 0); // streamid pos = avio_tell(pb); if (enc->codec_id == CODEC_ID_AAC) { avio_w8(pb, get_audio_flags(enc)); avio_w8(pb, 0); // AAC sequence header avio_write(pb, enc->extradata, enc->extradata_size); } else { avio_w8(pb, enc->codec_tag | FLV_FRAME_KEY); // flags avio_w8(pb, 0); // AVC sequence header avio_wb24(pb, 0); // composition time ff_isom_write_avcc(pb, enc->extradata, enc->extradata_size); } data_size = avio_tell(pb) - pos; avio_seek(pb, -data_size - 10, SEEK_CUR); avio_wb24(pb, data_size); avio_skip(pb, data_size + 10 - 3); avio_wb32(pb, data_size + 11); // previous tag size } } return 0; }
static int64_t seek_by_sector(AVIOContext *pb, int64_t sector, int64_t offset) { return avio_seek(pb, (sector << WTV_SECTOR_BITS) + offset, SEEK_SET); }
static int read_header(AVFormatContext *s) { AVIOContext *pb = s->pb; CaffContext *caf = s->priv_data; AVStream *st; uint32_t tag = 0; int found_data, ret; int64_t size; avio_skip(pb, 8); /* magic, version, file flags */ /* audio description chunk */ if (avio_rb32(pb) != MKBETAG('d','e','s','c')) { av_log(s, AV_LOG_ERROR, "desc chunk not present\n"); return AVERROR_INVALIDDATA; } size = avio_rb64(pb); if (size != 32) return AVERROR_INVALIDDATA; ret = read_desc_chunk(s); if (ret) return ret; st = s->streams[0]; /* parse each chunk */ found_data = 0; while (!pb->eof_reached) { /* stop at data chunk if seeking is not supported or data chunk size is unknown */ if (found_data && (caf->data_size < 0 || !pb->seekable)) break; tag = avio_rb32(pb); size = avio_rb64(pb); if (pb->eof_reached) break; switch (tag) { case MKBETAG('d','a','t','a'): avio_skip(pb, 4); /* edit count */ caf->data_start = avio_tell(pb); caf->data_size = size < 0 ? -1 : size - 4; if (caf->data_size > 0 && pb->seekable) avio_skip(pb, caf->data_size); found_data = 1; break; case MKBETAG('c','h','a','n'): if ((ret = ff_mov_read_chan(s, s->pb, st, size)) < 0) return ret; break; /* magic cookie chunk */ case MKBETAG('k','u','k','i'): if (read_kuki_chunk(s, size)) return AVERROR_INVALIDDATA; break; /* packet table chunk */ case MKBETAG('p','a','k','t'): if (read_pakt_chunk(s, size)) return AVERROR_INVALIDDATA; break; case MKBETAG('i','n','f','o'): read_info_chunk(s, size); break; default: #define _(x) ((x) >= ' ' ? (x) : ' ') av_log(s, AV_LOG_WARNING, "skipping CAF chunk: %08"PRIX32" (%"PRIu8"%"PRIu8"%"PRIu8"%"PRIu8")\n", tag, _(tag>>24), _((tag>>16)&0xFF), _((tag>>8)&0xFF), _(tag&0xFF)); #undef _ case MKBETAG('f','r','e','e'): if (size < 0) return AVERROR_INVALIDDATA; avio_skip(pb, size); break; } } if (!found_data) return AVERROR_INVALIDDATA; if (caf->bytes_per_packet > 0 && caf->frames_per_packet > 0) { if (caf->data_size > 0) st->nb_frames = (caf->data_size / caf->bytes_per_packet) * caf->frames_per_packet; } else if (st->nb_index_entries) { st->codec->bit_rate = st->codec->sample_rate * caf->data_size * 8 / st->duration; } else { av_log(s, AV_LOG_ERROR, "Missing packet table. It is required when " "block size or frame size are variable.\n"); return AVERROR_INVALIDDATA; } avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate); st->start_time = 0; /* position the stream at the start of data */ if (caf->data_size >= 0) avio_seek(pb, caf->data_start, SEEK_SET); return 0; }
static int rm_read_header(AVFormatContext *s) { RMDemuxContext *rm = s->priv_data; AVStream *st; AVIOContext *pb = s->pb; unsigned int tag; int tag_size; unsigned int start_time, duration; unsigned int data_off = 0, indx_off = 0; char buf[128], mime[128]; int flags = 0; tag = avio_rl32(pb); if (tag == MKTAG('.', 'r', 'a', 0xfd)) { /* very old .ra format */ return rm_read_header_old(s); } else if (tag != MKTAG('.', 'R', 'M', 'F')) { return AVERROR(EIO); } tag_size = avio_rb32(pb); avio_skip(pb, tag_size - 8); for(;;) { if (avio_feof(pb)) return -1; tag = avio_rl32(pb); tag_size = avio_rb32(pb); avio_rb16(pb); av_dlog(s, "tag=%c%c%c%c (%08x) size=%d\n", (tag ) & 0xff, (tag >> 8) & 0xff, (tag >> 16) & 0xff, (tag >> 24) & 0xff, tag, tag_size); if (tag_size < 10 && tag != MKTAG('D', 'A', 'T', 'A')) return -1; switch(tag) { case MKTAG('P', 'R', 'O', 'P'): /* file header */ avio_rb32(pb); /* max bit rate */ avio_rb32(pb); /* avg bit rate */ avio_rb32(pb); /* max packet size */ avio_rb32(pb); /* avg packet size */ avio_rb32(pb); /* nb packets */ duration = avio_rb32(pb); /* duration */ s->duration = av_rescale(duration, AV_TIME_BASE, 1000); avio_rb32(pb); /* preroll */ indx_off = avio_rb32(pb); /* index offset */ data_off = avio_rb32(pb); /* data offset */ avio_rb16(pb); /* nb streams */ flags = avio_rb16(pb); /* flags */ break; case MKTAG('C', 'O', 'N', 'T'): rm_read_metadata(s, pb, 1); break; case MKTAG('M', 'D', 'P', 'R'): st = avformat_new_stream(s, NULL); if (!st) return AVERROR(ENOMEM); st->id = avio_rb16(pb); avio_rb32(pb); /* max bit rate */ st->codec->bit_rate = avio_rb32(pb); /* bit rate */ avio_rb32(pb); /* max packet size */ avio_rb32(pb); /* avg packet size */ start_time = avio_rb32(pb); /* start time */ avio_rb32(pb); /* preroll */ duration = avio_rb32(pb); /* duration */ st->start_time = start_time; st->duration = duration; if(duration>0) s->duration = AV_NOPTS_VALUE; get_str8(pb, buf, sizeof(buf)); /* desc */ get_str8(pb, mime, sizeof(mime)); /* mimetype */ st->codec->codec_type = AVMEDIA_TYPE_DATA; st->priv_data = ff_rm_alloc_rmstream(); if (ff_rm_read_mdpr_codecdata(s, s->pb, st, st->priv_data, avio_rb32(pb), mime) < 0) return -1; break; case MKTAG('D', 'A', 'T', 'A'): goto header_end; default: /* unknown tag: skip it */ avio_skip(pb, tag_size - 10); break; } } header_end: rm->nb_packets = avio_rb32(pb); /* number of packets */ if (!rm->nb_packets && (flags & 4)) rm->nb_packets = 3600 * 25; avio_rb32(pb); /* next data header */ if (!data_off) data_off = avio_tell(pb) - 18; if (indx_off && pb->seekable && !(s->flags & AVFMT_FLAG_IGNIDX) && avio_seek(pb, indx_off, SEEK_SET) >= 0) { rm_read_index(s); avio_seek(pb, data_off + 18, SEEK_SET); } return 0; }
static int ipmovie_read_header(AVFormatContext *s) { IPMVEContext *ipmovie = s->priv_data; AVIOContext *pb = s->pb; AVPacket pkt; AVStream *st; unsigned char chunk_preamble[CHUNK_PREAMBLE_SIZE]; int chunk_type, i; uint8_t signature_buffer[sizeof(signature)]; avio_read(pb, signature_buffer, sizeof(signature_buffer)); while (memcmp(signature_buffer, signature, sizeof(signature))) { memmove(signature_buffer, signature_buffer + 1, sizeof(signature_buffer) - 1); signature_buffer[sizeof(signature_buffer) - 1] = avio_r8(pb); if (url_feof(pb)) return AVERROR_EOF; } /* initialize private context members */ ipmovie->video_pts = ipmovie->audio_frame_count = 0; ipmovie->audio_chunk_offset = ipmovie->video_chunk_offset = ipmovie->decode_map_chunk_offset = 0; /* on the first read, this will position the stream at the first chunk */ ipmovie->next_chunk_offset = avio_tell(pb) + 4; for (i = 0; i < 256; i++) ipmovie->palette[i] = 0xFFU << 24; /* process the first chunk which should be CHUNK_INIT_VIDEO */ if (process_ipmovie_chunk(ipmovie, pb, &pkt) != CHUNK_INIT_VIDEO) return AVERROR_INVALIDDATA; /* peek ahead to the next chunk-- if it is an init audio chunk, process * it; if it is the first video chunk, this is a silent file */ if (avio_read(pb, chunk_preamble, CHUNK_PREAMBLE_SIZE) != CHUNK_PREAMBLE_SIZE) return AVERROR(EIO); chunk_type = AV_RL16(&chunk_preamble[2]); avio_seek(pb, -CHUNK_PREAMBLE_SIZE, SEEK_CUR); if (chunk_type == CHUNK_VIDEO) ipmovie->audio_type = AV_CODEC_ID_NONE; /* no audio */ else if (process_ipmovie_chunk(ipmovie, pb, &pkt) != CHUNK_INIT_AUDIO) return AVERROR_INVALIDDATA; /* initialize the stream decoders */ st = avformat_new_stream(s, NULL); if (!st) return AVERROR(ENOMEM); avpriv_set_pts_info(st, 63, 1, 1000000); ipmovie->video_stream_index = st->index; st->codec->codec_type = AVMEDIA_TYPE_VIDEO; st->codec->codec_id = AV_CODEC_ID_INTERPLAY_VIDEO; st->codec->codec_tag = 0; /* no fourcc */ st->codec->width = ipmovie->video_width; st->codec->height = ipmovie->video_height; st->codec->bits_per_coded_sample = ipmovie->video_bpp; if (ipmovie->audio_type) { st = avformat_new_stream(s, NULL); if (!st) return AVERROR(ENOMEM); avpriv_set_pts_info(st, 32, 1, ipmovie->audio_sample_rate); ipmovie->audio_stream_index = st->index; st->codec->codec_type = AVMEDIA_TYPE_AUDIO; st->codec->codec_id = ipmovie->audio_type; st->codec->codec_tag = 0; /* no tag */ st->codec->channels = ipmovie->audio_channels; st->codec->sample_rate = ipmovie->audio_sample_rate; st->codec->bits_per_coded_sample = ipmovie->audio_bits; st->codec->bit_rate = st->codec->channels * st->codec->sample_rate * st->codec->bits_per_coded_sample; if (st->codec->codec_id == AV_CODEC_ID_INTERPLAY_DPCM) st->codec->bit_rate /= 2; st->codec->block_align = st->codec->channels * st->codec->bits_per_coded_sample; } return 0; }
static int ea_read_packet(AVFormatContext *s, AVPacket *pkt) { EaDemuxContext *ea = s->priv_data; AVIOContext *pb = s->pb; int partial_packet = 0; unsigned int chunk_type, chunk_size; int ret = 0, packet_read = 0, key = 0; int av_uninit(num_samples); while (!packet_read || partial_packet) { chunk_type = avio_rl32(pb); chunk_size = ea->big_endian ? avio_rb32(pb) : avio_rl32(pb); if (chunk_size <= 8) return AVERROR_INVALIDDATA; chunk_size -= 8; switch (chunk_type) { /* audio data */ case ISNh_TAG: /* header chunk also contains data; skip over the header portion */ if (chunk_size < 32) return AVERROR_INVALIDDATA; avio_skip(pb, 32); chunk_size -= 32; case ISNd_TAG: case SCDl_TAG: case SNDC_TAG: case SDEN_TAG: if (!ea->audio_codec) { avio_skip(pb, chunk_size); break; } else if (ea->audio_codec == AV_CODEC_ID_PCM_S16LE_PLANAR || ea->audio_codec == AV_CODEC_ID_MP3) { num_samples = avio_rl32(pb); avio_skip(pb, 8); chunk_size -= 12; } if (partial_packet) { avpriv_request_sample(s, "video header followed by audio packet"); av_free_packet(pkt); partial_packet = 0; } ret = av_get_packet(pb, pkt, chunk_size); if (ret < 0) return ret; pkt->stream_index = ea->audio_stream_index; switch (ea->audio_codec) { case AV_CODEC_ID_ADPCM_EA: case AV_CODEC_ID_ADPCM_EA_R1: case AV_CODEC_ID_ADPCM_EA_R2: case AV_CODEC_ID_ADPCM_IMA_EA_EACS: case AV_CODEC_ID_ADPCM_EA_R3: if (pkt->size < 4) { av_log(s, AV_LOG_ERROR, "Packet is too short\n"); av_free_packet(pkt); return AVERROR_INVALIDDATA; } if (ea->audio_codec == AV_CODEC_ID_ADPCM_EA_R3) pkt->duration = AV_RB32(pkt->data); else pkt->duration = AV_RL32(pkt->data); break; case AV_CODEC_ID_ADPCM_IMA_EA_SEAD: pkt->duration = ret * 2 / ea->num_channels; break; case AV_CODEC_ID_PCM_S16LE_PLANAR: case AV_CODEC_ID_MP3: pkt->duration = num_samples; break; default: pkt->duration = chunk_size / (ea->bytes * ea->num_channels); } packet_read = 1; break; /* ending tag */ case 0: case ISNe_TAG: case SCEl_TAG: case SEND_TAG: case SEEN_TAG: ret = AVERROR(EIO); packet_read = 1; break; case MVIh_TAG: case kVGT_TAG: case pQGT_TAG: case TGQs_TAG: case MADk_TAG: key = AV_PKT_FLAG_KEY; case MVIf_TAG: case fVGT_TAG: case MADm_TAG: case MADe_TAG: avio_seek(pb, -8, SEEK_CUR); // include chunk preamble chunk_size += 8; goto get_video_packet; case mTCD_TAG: avio_skip(pb, 8); // skip ea DCT header chunk_size -= 8; goto get_video_packet; case MV0K_TAG: case MPCh_TAG: case pIQT_TAG: key = AV_PKT_FLAG_KEY; case MV0F_TAG: get_video_packet: if (partial_packet) { ret = av_append_packet(pb, pkt, chunk_size); } else ret = av_get_packet(pb, pkt, chunk_size); if (ret < 0) { packet_read = 1; break; } partial_packet = chunk_type == MVIh_TAG; pkt->stream_index = ea->video_stream_index; pkt->flags |= key; packet_read = 1; break; default: avio_skip(pb, chunk_size); break; } } if (ret < 0 && partial_packet) av_free_packet(pkt); return ret; }
/** * Write an RTP hint (that may contain one or more RTP packets) * for the packets in data. data contains one or more packets with a * BE32 size header. * * @param out buffer where the hints are written * @param data buffer containing RTP packets * @param size the size of the data buffer * @param trk the MOVTrack for the hint track * @param pts pointer where the timestamp for the written RTP hint is stored * @return the number of RTP packets in the written hint */ static int write_hint_packets(AVIOContext *out, const uint8_t *data, int size, MOVTrack *trk, int64_t *pts) { int64_t curpos; int64_t count_pos, entries_pos; int count = 0, entries; count_pos = avio_tell(out); /* RTPsample header */ avio_wb16(out, 0); /* packet count */ avio_wb16(out, 0); /* reserved */ while (size > 4) { uint32_t packet_len = AV_RB32(data); uint16_t seq; uint32_t ts; data += 4; size -= 4; if (packet_len > size || packet_len <= 12) break; if (data[1] >= 200 && data[1] <= 204) { /* RTCP packet, just skip */ data += packet_len; size -= packet_len; continue; } if (packet_len > trk->max_packet_size) trk->max_packet_size = packet_len; seq = AV_RB16(&data[2]); ts = AV_RB32(&data[4]); if (trk->prev_rtp_ts == 0) trk->prev_rtp_ts = ts; /* Unwrap the 32-bit RTP timestamp that wraps around often * into a not (as often) wrapping 64-bit timestamp. */ trk->cur_rtp_ts_unwrapped += (int32_t) (ts - trk->prev_rtp_ts); trk->prev_rtp_ts = ts; if (*pts == AV_NOPTS_VALUE) *pts = trk->cur_rtp_ts_unwrapped; count++; /* RTPpacket header */ avio_wb32(out, 0); /* relative_time */ avio_write(out, data, 2); /* RTP header */ avio_wb16(out, seq); /* RTPsequenceseed */ avio_wb16(out, 0); /* reserved + flags */ entries_pos = avio_tell(out); avio_wb16(out, 0); /* entry count */ data += 12; size -= 12; packet_len -= 12; entries = 0; /* Write one or more constructors describing the payload data */ describe_payload(data, packet_len, out, &entries, &trk->sample_queue); data += packet_len; size -= packet_len; curpos = avio_tell(out); avio_seek(out, entries_pos, SEEK_SET); avio_wb16(out, entries); avio_seek(out, curpos, SEEK_SET); } curpos = avio_tell(out); avio_seek(out, count_pos, SEEK_SET); avio_wb16(out, count); avio_seek(out, curpos, SEEK_SET); return count; }
/* wav input */ static int wav_read_header(AVFormatContext *s, AVFormatParameters *ap) { int64_t size, av_uninit(data_size); int64_t sample_count=0; int rf64; unsigned int tag; AVIOContext *pb = s->pb; AVStream *st; WAVContext *wav = s->priv_data; /* check RIFF header */ tag = avio_rl32(pb); rf64 = tag == MKTAG('R', 'F', '6', '4'); if (!rf64 && tag != MKTAG('R', 'I', 'F', 'F')) return -1; avio_rl32(pb); /* file size */ tag = avio_rl32(pb); if (tag != MKTAG('W', 'A', 'V', 'E')) return -1; if (rf64) { if (avio_rl32(pb) != MKTAG('d', 's', '6', '4')) return -1; size = avio_rl32(pb); if (size < 16) return -1; avio_rl64(pb); /* RIFF size */ data_size = avio_rl64(pb); sample_count = avio_rl64(pb); avio_seek(pb, size - 16, SEEK_CUR); /* skip rest of ds64 chunk */ } /* parse fmt header */ size = find_tag(pb, MKTAG('f', 'm', 't', ' ')); if (size < 0) return -1; st = av_new_stream(s, 0); if (!st) return AVERROR(ENOMEM); ff_get_wav_header(pb, st->codec, size); st->need_parsing = AVSTREAM_PARSE_FULL; av_set_pts_info(st, 64, 1, st->codec->sample_rate); for (;;) { if (url_feof(pb)) return -1; size = next_tag(pb, &tag); if (tag == MKTAG('d', 'a', 't', 'a')){ break; }else if (tag == MKTAG('f','a','c','t') && !sample_count){ sample_count = avio_rl32(pb); size -= 4; } avio_seek(pb, size, SEEK_CUR); } if (rf64) size = data_size; if (size < 0) return -1; if (!size) { wav->data_end = INT64_MAX; } else wav->data_end= avio_tell(pb) + size; if (!sample_count && st->codec->channels && av_get_bits_per_sample(st->codec->codec_id)) sample_count = (size<<3) / (st->codec->channels * (uint64_t)av_get_bits_per_sample(st->codec->codec_id)); if (sample_count) st->duration = sample_count; return 0; }
static int rpl_read_header(AVFormatContext *s, AVFormatParameters *ap) { AVIOContext *pb = s->pb; RPLContext *rpl = s->priv_data; AVStream *vst = NULL, *ast = NULL; int total_audio_size; int error = 0; uint32_t i; int32_t audio_format, chunk_catalog_offset, number_of_chunks; AVRational fps; char line[RPL_LINE_LENGTH]; // The header for RPL/ARMovie files is 21 lines of text // containing the various header fields. The fields are always // in the same order, and other text besides the first // number usually isn't important. // (The spec says that there exists some significance // for the text in a few cases; samples needed.) error |= read_line(pb, line, sizeof(line)); // ARMovie error |= read_line(pb, line, sizeof(line)); // movie name av_dict_set(&s->metadata, "title" , line, 0); error |= read_line(pb, line, sizeof(line)); // date/copyright av_dict_set(&s->metadata, "copyright", line, 0); error |= read_line(pb, line, sizeof(line)); // author and other av_dict_set(&s->metadata, "author" , line, 0); // video headers vst = av_new_stream(s, 0); if (!vst) return AVERROR(ENOMEM); vst->codec->codec_type = AVMEDIA_TYPE_VIDEO; vst->codec->codec_tag = read_line_and_int(pb, &error); // video format vst->codec->width = read_line_and_int(pb, &error); // video width vst->codec->height = read_line_and_int(pb, &error); // video height vst->codec->bits_per_coded_sample = read_line_and_int(pb, &error); // video bits per sample error |= read_line(pb, line, sizeof(line)); // video frames per second fps = read_fps(line, &error); av_set_pts_info(vst, 32, fps.den, fps.num); // Figure out the video codec switch (vst->codec->codec_tag) { #if 0 case 122: vst->codec->codec_id = CODEC_ID_ESCAPE122; break; #endif case 124: vst->codec->codec_id = CODEC_ID_ESCAPE124; // The header is wrong here, at least sometimes vst->codec->bits_per_coded_sample = 16; break; #if 0 case 130: vst->codec->codec_id = CODEC_ID_ESCAPE130; break; #endif default: av_log(s, AV_LOG_WARNING, "RPL video format %i not supported yet!\n", vst->codec->codec_tag); vst->codec->codec_id = CODEC_ID_NONE; } // Audio headers // ARMovie supports multiple audio tracks; I don't have any // samples, though. This code will ignore additional tracks. audio_format = read_line_and_int(pb, &error); // audio format ID if (audio_format) { ast = av_new_stream(s, 0); if (!ast) return AVERROR(ENOMEM); ast->codec->codec_type = AVMEDIA_TYPE_AUDIO; ast->codec->codec_tag = audio_format; ast->codec->sample_rate = read_line_and_int(pb, &error); // audio bitrate ast->codec->channels = read_line_and_int(pb, &error); // number of audio channels ast->codec->bits_per_coded_sample = read_line_and_int(pb, &error); // audio bits per sample // At least one sample uses 0 for ADPCM, which is really 4 bits // per sample. if (ast->codec->bits_per_coded_sample == 0) ast->codec->bits_per_coded_sample = 4; ast->codec->bit_rate = ast->codec->sample_rate * ast->codec->bits_per_coded_sample * ast->codec->channels; ast->codec->codec_id = CODEC_ID_NONE; switch (audio_format) { case 1: if (ast->codec->bits_per_coded_sample == 16) { // 16-bit audio is always signed ast->codec->codec_id = CODEC_ID_PCM_S16LE; break; } // There are some other formats listed as legal per the spec; // samples needed. break; case 101: if (ast->codec->bits_per_coded_sample == 8) { // The samples with this kind of audio that I have // are all unsigned. ast->codec->codec_id = CODEC_ID_PCM_U8; break; } else if (ast->codec->bits_per_coded_sample == 4) { ast->codec->codec_id = CODEC_ID_ADPCM_IMA_EA_SEAD; break; } break; } if (ast->codec->codec_id == CODEC_ID_NONE) { av_log(s, AV_LOG_WARNING, "RPL audio format %i not supported yet!\n", audio_format); } av_set_pts_info(ast, 32, 1, ast->codec->bit_rate); } else { for (i = 0; i < 3; i++) error |= read_line(pb, line, sizeof(line)); } rpl->frames_per_chunk = read_line_and_int(pb, &error); // video frames per chunk if (rpl->frames_per_chunk > 1 && vst->codec->codec_tag != 124) av_log(s, AV_LOG_WARNING, "Don't know how to split frames for video format %i. " "Video stream will be broken!\n", vst->codec->codec_tag); number_of_chunks = read_line_and_int(pb, &error); // number of chunks in the file // The number in the header is actually the index of the last chunk. number_of_chunks++; error |= read_line(pb, line, sizeof(line)); // "even" chunk size in bytes error |= read_line(pb, line, sizeof(line)); // "odd" chunk size in bytes chunk_catalog_offset = // offset of the "chunk catalog" read_line_and_int(pb, &error); // (file index) error |= read_line(pb, line, sizeof(line)); // offset to "helpful" sprite error |= read_line(pb, line, sizeof(line)); // size of "helpful" sprite error |= read_line(pb, line, sizeof(line)); // offset to key frame list // Read the index avio_seek(pb, chunk_catalog_offset, SEEK_SET); total_audio_size = 0; for (i = 0; i < number_of_chunks; i++) { int64_t offset, video_size, audio_size; error |= read_line(pb, line, sizeof(line)); if (3 != sscanf(line, "%"PRId64" , %"PRId64" ; %"PRId64, &offset, &video_size, &audio_size)) error = -1; av_add_index_entry(vst, offset, i * rpl->frames_per_chunk, video_size, rpl->frames_per_chunk, 0); if (ast) av_add_index_entry(ast, offset + video_size, total_audio_size, audio_size, audio_size * 8, 0); total_audio_size += audio_size * 8; } if (error) return AVERROR(EIO); return 0; }
static int rpl_read_packet(AVFormatContext *s, AVPacket *pkt) { RPLContext *rpl = s->priv_data; AVIOContext *pb = s->pb; AVStream* stream; AVIndexEntry* index_entry; uint32_t ret; if (rpl->chunk_part == s->nb_streams) { rpl->chunk_number++; rpl->chunk_part = 0; } stream = s->streams[rpl->chunk_part]; if (rpl->chunk_number >= stream->nb_index_entries) return -1; index_entry = &stream->index_entries[rpl->chunk_number]; if (rpl->frame_in_part == 0) if (avio_seek(pb, index_entry->pos, SEEK_SET) < 0) return AVERROR(EIO); if (stream->codec->codec_type == AVMEDIA_TYPE_VIDEO && stream->codec->codec_tag == 124) { // We have to split Escape 124 frames because there are // multiple frames per chunk in Escape 124 samples. uint32_t frame_size; avio_skip(pb, 4); /* flags */ frame_size = avio_rl32(pb); if (avio_seek(pb, -8, SEEK_CUR) < 0) return AVERROR(EIO); ret = av_get_packet(pb, pkt, frame_size); if (ret != frame_size) { av_free_packet(pkt); return AVERROR(EIO); } pkt->duration = 1; pkt->pts = index_entry->timestamp + rpl->frame_in_part; pkt->stream_index = rpl->chunk_part; rpl->frame_in_part++; if (rpl->frame_in_part == rpl->frames_per_chunk) { rpl->frame_in_part = 0; rpl->chunk_part++; } } else { ret = av_get_packet(pb, pkt, index_entry->size); if (ret != index_entry->size) { av_free_packet(pkt); return AVERROR(EIO); } if (stream->codec->codec_type == AVMEDIA_TYPE_VIDEO) { // frames_per_chunk should always be one here; the header // parsing will warn if it isn't. pkt->duration = rpl->frames_per_chunk; } else { // All the audio codecs supported in this container // (at least so far) are constant-bitrate. pkt->duration = ret * 8; } pkt->pts = index_entry->timestamp; pkt->stream_index = rpl->chunk_part; rpl->chunk_part++; } // None of the Escape formats have keyframes, and the ADPCM // format used doesn't have keyframes. if (rpl->chunk_number == 0 && rpl->frame_in_part == 0) pkt->flags |= AV_PKT_FLAG_KEY; return ret; }
static int thp_read_header(AVFormatContext *s, AVFormatParameters *ap) { ThpDemuxContext *thp = (ThpDemuxContext *)s->priv_data; AVStream *st; AVIOContext *pb = s->pb; int64_t fsize= avio_size(pb); int i; /* Read the file header. */ avio_rb32(pb); /* Skip Magic. */ thp->version = avio_rb32(pb); avio_rb32(pb); /* Max buf size. */ avio_rb32(pb); /* Max samples. */ thp->fps = av_d2q(av_int2float(avio_rb32(pb)), INT_MAX); thp->framecnt = avio_rb32(pb); thp->first_framesz = avio_rb32(pb); pb->maxsize = avio_rb32(pb); if(fsize>0 && (!pb->maxsize || fsize < pb->maxsize)) pb->maxsize= fsize; thp->compoff = avio_rb32(pb); avio_rb32(pb); /* offsetDataOffset. */ thp->first_frame = avio_rb32(pb); thp->last_frame = avio_rb32(pb); thp->next_framesz = thp->first_framesz; thp->next_frame = thp->first_frame; /* Read the component structure. */ avio_seek (pb, thp->compoff, SEEK_SET); thp->compcount = avio_rb32(pb); /* Read the list of component types. */ avio_read(pb, thp->components, 16); for (i = 0; i < thp->compcount; i++) { if (thp->components[i] == 0) { if (thp->vst != 0) break; /* Video component. */ st = avformat_new_stream(s, NULL); if (!st) return AVERROR(ENOMEM); /* The denominator and numerator are switched because 1/fps is required. */ avpriv_set_pts_info(st, 64, thp->fps.den, thp->fps.num); st->codec->codec_type = AVMEDIA_TYPE_VIDEO; st->codec->codec_id = CODEC_ID_THP; st->codec->codec_tag = 0; /* no fourcc */ st->codec->width = avio_rb32(pb); st->codec->height = avio_rb32(pb); st->codec->sample_rate = av_q2d(thp->fps); thp->vst = st; thp->video_stream_index = st->index; if (thp->version == 0x11000) avio_rb32(pb); /* Unknown. */ } else if (thp->components[i] == 1) { if (thp->has_audio != 0) break; /* Audio component. */ st = avformat_new_stream(s, NULL); if (!st) return AVERROR(ENOMEM); st->codec->codec_type = AVMEDIA_TYPE_AUDIO; st->codec->codec_id = CODEC_ID_ADPCM_THP; st->codec->codec_tag = 0; /* no fourcc */ st->codec->channels = avio_rb32(pb); /* numChannels. */ st->codec->sample_rate = avio_rb32(pb); /* Frequency. */ avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate); thp->audio_stream_index = st->index; thp->has_audio = 1; } } return 0; }
static int mpjpeg_read_packet(AVFormatContext *s, AVPacket *pkt) { int size; int ret; MPJPEGDemuxContext *mpjpeg = s->priv_data; if (mpjpeg->boundary == NULL) { uint8_t* boundary = NULL; if (mpjpeg->strict_mime_boundary) { boundary = mpjpeg_get_boundary(s->pb); } if (boundary != NULL) { mpjpeg->boundary = boundary; mpjpeg->searchstr = av_asprintf( "\r\n%s\r\n", boundary ); } else { mpjpeg->boundary = av_strdup("--"); mpjpeg->searchstr = av_strdup("\r\n--"); } if (!mpjpeg->boundary || !mpjpeg->searchstr) { av_freep(&mpjpeg->boundary); av_freep(&mpjpeg->searchstr); return AVERROR(ENOMEM); } mpjpeg->searchstr_len = strlen(mpjpeg->searchstr); } ret = parse_multipart_header(s->pb, &size, mpjpeg->boundary, s); if (ret < 0) return ret; if (size > 0) { /* size has been provided to us in MIME header */ ret = av_get_packet(s->pb, pkt, size); } else { /* no size was given -- we read until the next boundary or end-of-file */ int remaining = 0, len; const int read_chunk = 2048; av_init_packet(pkt); pkt->data = NULL; pkt->size = 0; pkt->pos = avio_tell(s->pb); /* we may need to return as much as all we've read back to the buffer */ ffio_ensure_seekback(s->pb, read_chunk); while ((ret = av_append_packet(s->pb, pkt, read_chunk - remaining)) >= 0) { /* scan the new data */ char *start; len = ret + remaining; start = pkt->data + pkt->size - len; do { if (!memcmp(start, mpjpeg->searchstr, mpjpeg->searchstr_len)) { // got the boundary! rewind the stream avio_seek(s->pb, -(len-2), SEEK_CUR); pkt->size -= (len-2); return pkt->size; } len--; start++; } while (len >= mpjpeg->searchstr_len); remaining = len; } /* error or EOF occurred */ if (ret == AVERROR_EOF) { ret = pkt->size > 0 ? pkt->size : AVERROR_EOF; } else { av_packet_unref(pkt); } } return ret; }
static int read_packet(AVFormatContext *s, AVPacket *pkt) { AVIOContext *pb = s->pb; C93DemuxContext *c93 = s->priv_data; C93BlockRecord *br = &c93->block_records[c93->current_block]; int datasize; int ret, i; if (c93->next_pkt_is_audio) { c93->current_frame++; c93->next_pkt_is_audio = 0; datasize = avio_rl16(pb); if (datasize > 42) { if (!c93->audio) { c93->audio = avformat_new_stream(s, NULL); if (!c93->audio) return AVERROR(ENOMEM); c93->audio->codecpar->codec_type = AVMEDIA_TYPE_AUDIO; } avio_skip(pb, 26); /* VOC header */ ret = ff_voc_get_packet(s, pkt, c93->audio, datasize - 26); if (ret > 0) { pkt->stream_index = 1; pkt->flags |= AV_PKT_FLAG_KEY; return ret; } } } if (c93->current_frame >= br->frames) { if (c93->current_block >= 511 || !br[1].length) return AVERROR_EOF; br++; c93->current_block++; c93->current_frame = 0; } if (c93->current_frame == 0) { avio_seek(pb, br->index * 2048, SEEK_SET); for (i = 0; i < 32; i++) { c93->frame_offsets[i] = avio_rl32(pb); } } avio_seek(pb,br->index * 2048 + c93->frame_offsets[c93->current_frame], SEEK_SET); datasize = avio_rl16(pb); /* video frame size */ ret = av_new_packet(pkt, datasize + 768 + 1); if (ret < 0) return ret; pkt->data[0] = 0; pkt->size = datasize + 1; ret = avio_read(pb, pkt->data + 1, datasize); if (ret < datasize) { ret = AVERROR(EIO); goto fail; } datasize = avio_rl16(pb); /* palette size */ if (datasize) { if (datasize != 768) { av_log(s, AV_LOG_ERROR, "invalid palette size %u\n", datasize); ret = AVERROR_INVALIDDATA; goto fail; } pkt->data[0] |= C93_HAS_PALETTE; ret = avio_read(pb, pkt->data + pkt->size, datasize); if (ret < datasize) { ret = AVERROR(EIO); goto fail; } pkt->size += 768; } pkt->stream_index = 0; c93->next_pkt_is_audio = 1; /* only the first frame is guaranteed to not reference previous frames */ if (c93->current_block == 0 && c93->current_frame == 0) { pkt->flags |= AV_PKT_FLAG_KEY; pkt->data[0] |= C93_FIRST_FRAME; } return 0; fail: av_packet_unref(pkt); return ret; }
static int gxf_write_umf_media_description(AVFormatContext *s) { GXFContext *gxf = s->priv_data; AVIOContext *pb = s->pb; int64_t pos; int i, j; pos = url_ftell(pb); gxf->umf_media_offset = pos - gxf->umf_start_offset; for (i = 0; i <= s->nb_streams; ++i) { GXFStreamContext *sc; int64_t startpos, curpos; if (i == s->nb_streams) sc = &gxf->timecode_track; else sc = s->streams[i]->priv_data; startpos = url_ftell(pb); avio_wl16(pb, 0); /* length */ avio_wl16(pb, sc->media_info); avio_wl16(pb, 0); /* reserved */ avio_wl16(pb, 0); /* reserved */ avio_wl32(pb, gxf->nb_fields); avio_wl32(pb, 0); /* attributes rw, ro */ avio_wl32(pb, 0); /* mark in */ avio_wl32(pb, gxf->nb_fields); /* mark out */ avio_write(pb, ES_NAME_PATTERN, strlen(ES_NAME_PATTERN)); avio_wb16(pb, sc->media_info); for (j = strlen(ES_NAME_PATTERN)+2; j < 88; j++) avio_w8(pb, 0); avio_wl32(pb, sc->track_type); avio_wl32(pb, sc->sample_rate); avio_wl32(pb, sc->sample_size); avio_wl32(pb, 0); /* reserved */ if (sc == &gxf->timecode_track) gxf_write_umf_media_timecode(pb, sc); /* 8 0bytes */ else { AVStream *st = s->streams[i]; switch (st->codec->codec_id) { case CODEC_ID_MPEG1VIDEO: case CODEC_ID_MPEG2VIDEO: gxf_write_umf_media_mpeg(pb, st); break; case CODEC_ID_PCM_S16LE: gxf_write_umf_media_audio(pb, sc); break; case CODEC_ID_DVVIDEO: gxf_write_umf_media_dv(pb, sc); break; } } curpos = url_ftell(pb); avio_seek(pb, startpos, SEEK_SET); avio_wl16(pb, curpos - startpos); avio_seek(pb, curpos, SEEK_SET); } return url_ftell(pb) - pos; }
static int film_read_packet(AVFormatContext *s, AVPacket *pkt) { FilmDemuxContext *film = s->priv_data; AVIOContext *pb = s->pb; film_sample *sample; int ret = 0; int i; int left, right; if (film->current_sample >= film->sample_count) return AVERROR(EIO); sample = &film->sample_table[film->current_sample]; /* position the stream (will probably be there anyway) */ avio_seek(pb, sample->sample_offset, SEEK_SET); /* do a special song and dance when loading FILM Cinepak chunks */ if ((sample->stream == film->video_stream_index) && (film->video_type == CODEC_ID_CINEPAK)) { pkt->pos= avio_tell(pb); if (av_new_packet(pkt, sample->sample_size)) return AVERROR(ENOMEM); avio_read(pb, pkt->data, sample->sample_size); } else if ((sample->stream == film->audio_stream_index) && (film->audio_channels == 2) && (film->audio_type != CODEC_ID_ADPCM_ADX)) { /* stereo PCM needs to be interleaved */ if (av_new_packet(pkt, sample->sample_size)) return AVERROR(ENOMEM); /* make sure the interleave buffer is large enough */ if (sample->sample_size > film->stereo_buffer_size) { av_free(film->stereo_buffer); film->stereo_buffer_size = sample->sample_size; film->stereo_buffer = av_malloc(film->stereo_buffer_size); } pkt->pos= avio_tell(pb); ret = avio_read(pb, film->stereo_buffer, sample->sample_size); if (ret != sample->sample_size) ret = AVERROR(EIO); left = 0; right = sample->sample_size / 2; for (i = 0; i < sample->sample_size; ) { if (film->audio_bits == 8) { pkt->data[i++] = film->stereo_buffer[left++]; pkt->data[i++] = film->stereo_buffer[right++]; } else { pkt->data[i++] = film->stereo_buffer[left++]; pkt->data[i++] = film->stereo_buffer[left++]; pkt->data[i++] = film->stereo_buffer[right++]; pkt->data[i++] = film->stereo_buffer[right++]; } } } else { ret= av_get_packet(pb, pkt, sample->sample_size); if (ret != sample->sample_size) ret = AVERROR(EIO); } pkt->stream_index = sample->stream; pkt->pts = sample->pts; film->current_sample++; return ret; }
static int load_ipmovie_packet(IPMVEContext *s, AVIOContext *pb, AVPacket *pkt) { int chunk_type; if (s->audio_chunk_offset && s->audio_channels && s->audio_bits) { if (s->audio_type == AV_CODEC_ID_NONE) { av_log(NULL, AV_LOG_ERROR, "Can not read audio packet before" "audio codec is known\n"); return CHUNK_BAD; } /* adjust for PCM audio by skipping chunk header */ if (s->audio_type != AV_CODEC_ID_INTERPLAY_DPCM) { s->audio_chunk_offset += 6; s->audio_chunk_size -= 6; } avio_seek(pb, s->audio_chunk_offset, SEEK_SET); s->audio_chunk_offset = 0; if (s->audio_chunk_size != av_get_packet(pb, pkt, s->audio_chunk_size)) return CHUNK_EOF; pkt->stream_index = s->audio_stream_index; pkt->pts = s->audio_frame_count; /* audio frame maintenance */ if (s->audio_type != AV_CODEC_ID_INTERPLAY_DPCM) s->audio_frame_count += (s->audio_chunk_size / s->audio_channels / (s->audio_bits / 8)); else s->audio_frame_count += (s->audio_chunk_size - 6 - s->audio_channels) / s->audio_channels; av_dlog(NULL, "sending audio frame with pts %"PRId64" (%d audio frames)\n", pkt->pts, s->audio_frame_count); chunk_type = CHUNK_VIDEO; } else if (s->decode_map_chunk_offset) { /* send both the decode map and the video data together */ if (av_new_packet(pkt, s->decode_map_chunk_size + s->video_chunk_size)) return CHUNK_NOMEM; if (s->has_palette) { uint8_t *pal; pal = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE, AVPALETTE_SIZE); if (pal) { memcpy(pal, s->palette, AVPALETTE_SIZE); s->has_palette = 0; } } if (s->changed) { ff_add_param_change(pkt, 0, 0, 0, s->video_width, s->video_height); s->changed = 0; } pkt->pos= s->decode_map_chunk_offset; avio_seek(pb, s->decode_map_chunk_offset, SEEK_SET); s->decode_map_chunk_offset = 0; if (avio_read(pb, pkt->data, s->decode_map_chunk_size) != s->decode_map_chunk_size) { av_free_packet(pkt); return CHUNK_EOF; } avio_seek(pb, s->video_chunk_offset, SEEK_SET); s->video_chunk_offset = 0; if (avio_read(pb, pkt->data + s->decode_map_chunk_size, s->video_chunk_size) != s->video_chunk_size) { av_free_packet(pkt); return CHUNK_EOF; } pkt->stream_index = s->video_stream_index; pkt->pts = s->video_pts; av_dlog(NULL, "sending video frame with pts %"PRId64"\n", pkt->pts); s->video_pts += s->frame_pts_inc; chunk_type = CHUNK_VIDEO; } else { avio_seek(pb, s->next_chunk_offset, SEEK_SET); chunk_type = CHUNK_DONE; } return chunk_type; }
static int dxa_read_header(AVFormatContext *s) { AVIOContext *pb = s->pb; DXAContext *c = s->priv_data; AVStream *st, *ast; uint32_t tag; int32_t fps; int w, h; int num, den; int flags; int ret; tag = avio_rl32(pb); if (tag != MKTAG('D', 'E', 'X', 'A')) return -1; flags = avio_r8(pb); c->frames = avio_rb16(pb); if(!c->frames){ av_log(s, AV_LOG_ERROR, "File contains no frames ???\n"); return -1; } fps = avio_rb32(pb); if(fps > 0){ den = 1000; num = fps; }else if (fps < 0){ den = 100000; num = -fps; }else{ den = 10; num = 1; } w = avio_rb16(pb); h = avio_rb16(pb); c->has_sound = 0; st = avformat_new_stream(s, NULL); if (!st) return -1; // Parse WAV data header if(avio_rl32(pb) == MKTAG('W', 'A', 'V', 'E')){ uint32_t size, fsize; c->has_sound = 1; size = avio_rb32(pb); c->vidpos = avio_tell(pb) + size; avio_skip(pb, 16); fsize = avio_rl32(pb); ast = avformat_new_stream(s, NULL); if (!ast) return -1; ret = ff_get_wav_header(pb, ast->codec, fsize); if (ret < 0) return ret; if (ast->codec->sample_rate > 0) avpriv_set_pts_info(ast, 64, 1, ast->codec->sample_rate); // find 'data' chunk while(avio_tell(pb) < c->vidpos && !url_feof(pb)){ tag = avio_rl32(pb); fsize = avio_rl32(pb); if(tag == MKTAG('d', 'a', 't', 'a')) break; avio_skip(pb, fsize); } c->bpc = (fsize + c->frames - 1) / c->frames; if(ast->codec->block_align) c->bpc = ((c->bpc + ast->codec->block_align - 1) / ast->codec->block_align) * ast->codec->block_align; c->bytes_left = fsize; c->wavpos = avio_tell(pb); avio_seek(pb, c->vidpos, SEEK_SET); } /* now we are ready: build format streams */ st->codec->codec_type = AVMEDIA_TYPE_VIDEO; st->codec->codec_id = CODEC_ID_DXA; st->codec->width = w; st->codec->height = h; av_reduce(&den, &num, den, num, (1UL<<31)-1); avpriv_set_pts_info(st, 33, num, den); /* flags & 0x80 means that image is interlaced, * flags & 0x40 means that image has double height * either way set true height */ if(flags & 0xC0){ st->codec->height >>= 1; }
/* Process EA file header. * Return 1 if the EA file is valid and successfully opened, 0 otherwise. */ static int process_ea_header(AVFormatContext *s) { uint32_t blockid, size = 0; EaDemuxContext *ea = s->priv_data; AVIOContext *pb = s->pb; int i; for (i = 0; i < 5 && (!ea->audio_codec || !ea->video_codec); i++) { unsigned int startpos = avio_tell(pb); int err = 0; blockid = avio_rl32(pb); size = avio_rl32(pb); if (i == 0) ea->big_endian = size > 0x000FFFFF; if (ea->big_endian) size = av_bswap32(size); switch (blockid) { case ISNh_TAG: if (avio_rl32(pb) != EACS_TAG) { avpriv_request_sample(s, "unknown 1SNh headerid"); return 0; } process_audio_header_eacs(s); break; case SCHl_TAG: case SHEN_TAG: blockid = avio_rl32(pb); if (blockid == GSTR_TAG) { avio_skip(pb, 4); } else if ((blockid & 0xFFFF) != PT00_TAG) { avpriv_request_sample(s, "unknown SCHl headerid"); return 0; } err = process_audio_header_elements(s); break; case SEAD_TAG: process_audio_header_sead(s); break; case MVIh_TAG: process_video_header_cmv(s); break; case kVGT_TAG: ea->video_codec = AV_CODEC_ID_TGV; break; case mTCD_TAG: process_video_header_mdec(s); break; case MPCh_TAG: ea->video_codec = AV_CODEC_ID_MPEG2VIDEO; break; case pQGT_TAG: case TGQs_TAG: ea->video_codec = AV_CODEC_ID_TGQ; break; case pIQT_TAG: ea->video_codec = AV_CODEC_ID_TQI; break; case MADk_TAG: ea->video_codec = AV_CODEC_ID_MAD; break; case MVhd_TAG: err = process_video_header_vp6(s); break; } if (err < 0) { av_log(s, AV_LOG_ERROR, "error parsing header: %i\n", err); return err; } avio_seek(pb, startpos + size, SEEK_SET); } avio_seek(pb, 0, SEEK_SET); return 1; }
static int smacker_read_packet(AVFormatContext *s, AVPacket *pkt) { SmackerContext *smk = s->priv_data; int flags; int ret; int i; int frame_size = 0; int palchange = 0; if (url_feof(s->pb) || smk->cur_frame >= smk->frames) return AVERROR_EOF; /* if we demuxed all streams, pass another frame */ if(smk->curstream < 0) { avio_seek(s->pb, smk->nextpos, 0); frame_size = smk->frm_size[smk->cur_frame] & (~3); flags = smk->frm_flags[smk->cur_frame]; /* handle palette change event */ if(flags & SMACKER_PAL){ int size, sz, t, off, j, pos; uint8_t *pal = smk->pal; uint8_t oldpal[768]; memcpy(oldpal, pal, 768); size = avio_r8(s->pb); size = size * 4 - 1; frame_size -= size; frame_size--; sz = 0; pos = avio_tell(s->pb) + size; while(sz < 256){ t = avio_r8(s->pb); if(t & 0x80){ /* skip palette entries */ sz += (t & 0x7F) + 1; pal += ((t & 0x7F) + 1) * 3; } else if(t & 0x40){ /* copy with offset */ off = avio_r8(s->pb) * 3; j = (t & 0x3F) + 1; while(j-- && sz < 256) { *pal++ = oldpal[off + 0]; *pal++ = oldpal[off + 1]; *pal++ = oldpal[off + 2]; sz++; off += 3; } } else { /* new entries */ *pal++ = smk_pal[t]; *pal++ = smk_pal[avio_r8(s->pb) & 0x3F]; *pal++ = smk_pal[avio_r8(s->pb) & 0x3F]; sz++; } } avio_seek(s->pb, pos, 0); palchange |= 1; } flags >>= 1; smk->curstream = -1; /* if audio chunks are present, put them to stack and retrieve later */ for(i = 0; i < 7; i++) { if(flags & 1) { int size; size = avio_rl32(s->pb) - 4; frame_size -= size; frame_size -= 4; smk->curstream++; smk->bufs[smk->curstream] = av_realloc(smk->bufs[smk->curstream], size); smk->buf_sizes[smk->curstream] = size; ret = avio_read(s->pb, smk->bufs[smk->curstream], size); if(ret != size) return AVERROR(EIO); smk->stream_id[smk->curstream] = smk->indexes[i]; } flags >>= 1; } if (av_new_packet(pkt, frame_size + 768)) return AVERROR(ENOMEM); if(smk->frm_size[smk->cur_frame] & 1) palchange |= 2; pkt->data[0] = palchange; memcpy(pkt->data + 1, smk->pal, 768); ret = avio_read(s->pb, pkt->data + 769, frame_size); if(ret != frame_size) return AVERROR(EIO); pkt->stream_index = smk->videoindex; pkt->size = ret + 769; smk->cur_frame++; smk->nextpos = avio_tell(s->pb); } else {
/* write the header (used two times if non streamed) */ static int asf_write_header1(AVFormatContext *s, int64_t file_size, int64_t data_chunk_size) { ASFContext *asf = s->priv_data; AVIOContext *pb = s->pb; AVDictionaryEntry *tags[5]; int header_size, n, extra_size, extra_size2, wav_extra_size, file_time; int has_title; int metadata_count; AVCodecContext *enc; int64_t header_offset, cur_pos, hpos; int bit_rate; int64_t duration; ff_metadata_conv(&s->metadata, ff_asf_metadata_conv, NULL); tags[0] = av_dict_get(s->metadata, "title" , NULL, 0); tags[1] = av_dict_get(s->metadata, "author" , NULL, 0); tags[2] = av_dict_get(s->metadata, "copyright", NULL, 0); tags[3] = av_dict_get(s->metadata, "comment" , NULL, 0); tags[4] = av_dict_get(s->metadata, "rating" , NULL, 0); duration = asf->duration + PREROLL_TIME * 10000; has_title = tags[0] || tags[1] || tags[2] || tags[3] || tags[4]; metadata_count = av_dict_count(s->metadata); bit_rate = 0; for(n=0;n<s->nb_streams;n++) { enc = s->streams[n]->codec; avpriv_set_pts_info(s->streams[n], 32, 1, 1000); /* 32 bit pts in ms */ bit_rate += enc->bit_rate; } if (asf->is_streamed) { put_chunk(s, 0x4824, 0, 0xc00); /* start of stream (length will be patched later) */ } ff_put_guid(pb, &ff_asf_header); avio_wl64(pb, -1); /* header length, will be patched after */ avio_wl32(pb, 3 + has_title + !!metadata_count + s->nb_streams); /* number of chunks in header */ avio_w8(pb, 1); /* ??? */ avio_w8(pb, 2); /* ??? */ /* file header */ header_offset = avio_tell(pb); hpos = put_header(pb, &ff_asf_file_header); ff_put_guid(pb, &ff_asf_my_guid); avio_wl64(pb, file_size); file_time = 0; avio_wl64(pb, unix_to_file_time(file_time)); avio_wl64(pb, asf->nb_packets); /* number of packets */ avio_wl64(pb, duration); /* end time stamp (in 100ns units) */ avio_wl64(pb, asf->duration); /* duration (in 100ns units) */ avio_wl64(pb, PREROLL_TIME); /* start time stamp */ avio_wl32(pb, (asf->is_streamed || !pb->seekable ) ? 3 : 2); /* ??? */ avio_wl32(pb, s->packet_size); /* packet size */ avio_wl32(pb, s->packet_size); /* packet size */ avio_wl32(pb, bit_rate); /* Nominal data rate in bps */ end_header(pb, hpos); /* unknown headers */ hpos = put_header(pb, &ff_asf_head1_guid); ff_put_guid(pb, &ff_asf_head2_guid); avio_wl32(pb, 6); avio_wl16(pb, 0); end_header(pb, hpos); /* title and other infos */ if (has_title) { int len; uint8_t *buf; AVIOContext *dyn_buf; if (avio_open_dyn_buf(&dyn_buf) < 0) return AVERROR(ENOMEM); hpos = put_header(pb, &ff_asf_comment_header); for (n = 0; n < FF_ARRAY_ELEMS(tags); n++) { len = tags[n] ? avio_put_str16le(dyn_buf, tags[n]->value) : 0; avio_wl16(pb, len); } len = avio_close_dyn_buf(dyn_buf, &buf); avio_write(pb, buf, len); av_freep(&buf); end_header(pb, hpos); } if (metadata_count) { AVDictionaryEntry *tag = NULL; hpos = put_header(pb, &ff_asf_extended_content_header); avio_wl16(pb, metadata_count); while ((tag = av_dict_get(s->metadata, "", tag, AV_DICT_IGNORE_SUFFIX))) { put_str16(pb, tag->key); avio_wl16(pb, 0); put_str16(pb, tag->value); } end_header(pb, hpos); } /* stream headers */ for(n=0;n<s->nb_streams;n++) { int64_t es_pos; // ASFStream *stream = &asf->streams[n]; enc = s->streams[n]->codec; asf->streams[n].num = n + 1; asf->streams[n].seq = 1; switch(enc->codec_type) { case AVMEDIA_TYPE_AUDIO: wav_extra_size = 0; extra_size = 18 + wav_extra_size; extra_size2 = 8; break; default: case AVMEDIA_TYPE_VIDEO: wav_extra_size = enc->extradata_size; extra_size = 0x33 + wav_extra_size; extra_size2 = 0; break; } hpos = put_header(pb, &ff_asf_stream_header); if (enc->codec_type == AVMEDIA_TYPE_AUDIO) { ff_put_guid(pb, &ff_asf_audio_stream); ff_put_guid(pb, &ff_asf_audio_conceal_spread); } else { ff_put_guid(pb, &ff_asf_video_stream); ff_put_guid(pb, &ff_asf_video_conceal_none); } avio_wl64(pb, 0); /* ??? */ es_pos = avio_tell(pb); avio_wl32(pb, extra_size); /* wav header len */ avio_wl32(pb, extra_size2); /* additional data len */ avio_wl16(pb, n + 1); /* stream number */ avio_wl32(pb, 0); /* ??? */ if (enc->codec_type == AVMEDIA_TYPE_AUDIO) { /* WAVEFORMATEX header */ int wavsize = ff_put_wav_header(pb, enc); if (wavsize < 0) return -1; if (wavsize != extra_size) { cur_pos = avio_tell(pb); avio_seek(pb, es_pos, SEEK_SET); avio_wl32(pb, wavsize); /* wav header len */ avio_seek(pb, cur_pos, SEEK_SET); } /* ERROR Correction */ avio_w8(pb, 0x01); if(enc->codec_id == AV_CODEC_ID_ADPCM_G726 || !enc->block_align){ avio_wl16(pb, 0x0190); avio_wl16(pb, 0x0190); }else{ avio_wl16(pb, enc->block_align); avio_wl16(pb, enc->block_align); } avio_wl16(pb, 0x01); avio_w8(pb, 0x00); } else { avio_wl32(pb, enc->width); avio_wl32(pb, enc->height); avio_w8(pb, 2); /* ??? */ avio_wl16(pb, 40 + enc->extradata_size); /* size */ /* BITMAPINFOHEADER header */ ff_put_bmp_header(pb, enc, ff_codec_bmp_tags, 1); } end_header(pb, hpos); } /* media comments */ hpos = put_header(pb, &ff_asf_codec_comment_header); ff_put_guid(pb, &ff_asf_codec_comment1_header); avio_wl32(pb, s->nb_streams); for(n=0;n<s->nb_streams;n++) { AVCodec *p; const char *desc; int len; uint8_t *buf; AVIOContext *dyn_buf; enc = s->streams[n]->codec; p = avcodec_find_encoder(enc->codec_id); if(enc->codec_type == AVMEDIA_TYPE_AUDIO) avio_wl16(pb, 2); else if(enc->codec_type == AVMEDIA_TYPE_VIDEO) avio_wl16(pb, 1); else avio_wl16(pb, -1); if(enc->codec_id == AV_CODEC_ID_WMAV2) desc = "Windows Media Audio V8"; else desc = p ? p->name : enc->codec_name; if ( avio_open_dyn_buf(&dyn_buf) < 0) return AVERROR(ENOMEM); avio_put_str16le(dyn_buf, desc); len = avio_close_dyn_buf(dyn_buf, &buf); avio_wl16(pb, len / 2); // "number of characters" = length in bytes / 2 avio_write(pb, buf, len); av_freep(&buf); avio_wl16(pb, 0); /* no parameters */ /* id */ if (enc->codec_type == AVMEDIA_TYPE_AUDIO) { avio_wl16(pb, 2); avio_wl16(pb, enc->codec_tag); } else { avio_wl16(pb, 4); avio_wl32(pb, enc->codec_tag); } if(!enc->codec_tag) return -1; } end_header(pb, hpos); /* patch the header size fields */ cur_pos = avio_tell(pb); header_size = cur_pos - header_offset; if (asf->is_streamed) { header_size += 8 + 30 + 50; avio_seek(pb, header_offset - 10 - 30, SEEK_SET); avio_wl16(pb, header_size); avio_seek(pb, header_offset - 2 - 30, SEEK_SET); avio_wl16(pb, header_size); header_size -= 8 + 30 + 50; } header_size += 24 + 6; avio_seek(pb, header_offset - 14, SEEK_SET); avio_wl64(pb, header_size); avio_seek(pb, cur_pos, SEEK_SET); /* movie chunk, followed by packets of packet_size */ asf->data_offset = cur_pos; ff_put_guid(pb, &ff_asf_data_header); avio_wl64(pb, data_chunk_size); ff_put_guid(pb, &ff_asf_my_guid); avio_wl64(pb, asf->nb_packets); /* nb packets */ avio_w8(pb, 1); /* ??? */ avio_w8(pb, 1); /* ??? */ return 0; }
static int cmf_parser_next_slice(AVFormatContext *s, int *index, int first) { int i, j, ret=-1; struct cmf *bs = s->priv_data; struct cmfvpb *oldvpb = bs->cmfvpb; struct cmfvpb *newvpb = NULL; AVInputFormat *in_fmt = NULL; av_log(s, AV_LOG_INFO, "cmf_parser_next_slice:%d\n", index); ret = cmfvpb_dup_pb(s->pb, &newvpb, index); if (ret < 0) { av_log(s, AV_LOG_INFO, "cmfvpb_dup_pb failed %s---%d [%d]\n",__FUNCTION__,__LINE__,ret); return ret; } if (bs->sctx) { avformat_free_context(bs->sctx); } bs->sctx = NULL; if (!(bs->sctx = avformat_alloc_context())) { av_log(s, AV_LOG_INFO, "cmf_parser_next_slice avformat_alloc_context failed!\n"); return AVERROR(ENOMEM); } ret = av_probe_input_buffer(newvpb->pb, &in_fmt, "", NULL, 0, 0); if (ret < 0) { av_log(s, AV_LOG_INFO, "av_probe_input_buffer failed %s---%d [%d]\n",__FUNCTION__,__LINE__,ret); if (bs->sctx) { avformat_free_context(bs->sctx); bs->sctx=NULL; } return ret; } bs->sctx->pb = newvpb->pb; ret = avformat_open_input(&bs->sctx, "", NULL, NULL); if (ret < 0) { av_log(s, AV_LOG_INFO, "cmf_parser_next_slice:avformat_open_input failed \n"); if (bs->sctx) { avformat_free_context(bs->sctx); bs->sctx=NULL; } goto fail; } if (!memcmp(bs->sctx->iformat->name,"flv",3)) { ret=av_find_stream_info(bs->sctx); av_log(s, AV_LOG_INFO, "xxx-------av_find_stream_info=%d",ret); } if (first) { /* Create new AVStreams for each stream in this chip Add into the Best format ; */ if (!memcmp(bs->sctx->iformat->name,"mov",3)) bs->next_mp4_flag = 1; for (j = 0; j < (int)bs->sctx->nb_streams ; j++) { AVStream *st = av_new_stream(s, 0); if (!st) { ret = AVERROR(ENOMEM); goto fail; } avcodec_copy_context(st->codec, bs->sctx->streams[j]->codec); } for (i = 0; i < (int)s->nb_streams ; i++) { AVStream *st = s->streams[i]; AVStream *sst = bs->sctx->streams[i]; st->id=sst->id; if (st->codec->codec_type == CODEC_TYPE_AUDIO) { st->time_base.den = sst->time_base.den; st->time_base.num = sst->time_base.num; bs->first_slice_audio_index = i; } if (st->codec->codec_type == CODEC_TYPE_VIDEO) { st->time_base.den = sst->time_base.den; st->time_base.num = sst->time_base.num; bs->first_mp4_video_base_time_num = sst->time_base.num; bs->first_mp4_video_base_time_den = sst->time_base.den; bs->first_slice_video_index = i; } } s->duration = newvpb->total_duration*1000; av_log(s, AV_LOG_INFO, "get duration [%lld]us [%lld]ms [%lld]s\n", s->duration,newvpb->total_duration,(newvpb->total_duration/1000)); } else { bs->stream_index_changed = 0; if (!memcmp(bs->sctx->iformat->name,"mpegts",6)) { if(bs->sctx->streams[bs->first_slice_audio_index]->codec->codec_type != s->streams[bs->first_slice_audio_index]->codec->codec_type) { bs->stream_index_changed = 1; AVStream *temp = NULL; AVStream *audio = bs->sctx->streams[bs->first_slice_audio_index]; temp = bs->sctx->streams[bs->first_slice_video_index]; bs->sctx->streams[bs->first_slice_video_index] = audio; bs->sctx->streams[bs->first_slice_audio_index] = temp; } } if (!memcmp(bs->sctx->iformat->name,"mov",3)) { #if 1 /* int audio_index = -1; int video_index = -1; AVStream *cmf_audio = NULL; AVStream *cmf_video = NULL; for (i = 0; i < (int)bs->sctx->nb_streams ; i++) { if(bs->sctx->streams[i]->codec->codec_type == CODEC_TYPE_AUDIO) cmf_audio = bs->sctx->streams[i]; if(bs->sctx->streams[i]->codec->codec_type == CODEC_TYPE_VIDEO) cmf_video = bs->sctx->streams[i]; } if(cmf_audio && cmf_video) {*/ for (i = 0; i < (int)s->nb_streams ; i++) { AVStream *st = s->streams[i]; AVStream *sst = bs->sctx->streams[i]; if (st->codec->codec_type == CODEC_TYPE_AUDIO) { st->time_base.den = sst->time_base.den; st->time_base.num = sst->time_base.num; //audio_index = i; } if (st->codec->codec_type == CODEC_TYPE_VIDEO) { st->time_base.den = sst->time_base.den; st->time_base.num = sst->time_base.num; //video_index = i; } if(st->codec->extradata) av_freep(&(st->codec->extradata)); if(sst->codec->extradata && sst->codec->extradata_size > 0) { st->codec->extradata = av_malloc(sst->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE); if(st->codec->extradata) { memcpy(st->codec->extradata, sst->codec->extradata, sst->codec->extradata_size); memset(((uint8_t *) st->codec->extradata) + sst->codec->extradata_size, 0, FF_INPUT_BUFFER_PADDING_SIZE); } } } /* if(audio_index >= 0 && bs->sctx->streams[bs->first_mp4_audio_index]->codec->codec_type != s->streams[audio_index]->codec->codec_type) { bs->stream_index_changed = 1; AVStream *temp = NULL; AVStream *audio = s->streams[audio_index]; temp = s->streams[video_index]; s->streams[video_index] = audio; s->streams[audio_index] = temp; av_log(NULL,AV_LOG_INFO,"--------->tao_cmf_index_change first_mp4_audio_index=%d, audio_index=%d, video_index=%d",bs->first_mp4_audio_index,audio_index,video_index); }*/ bs->next_mp4_flag = 1; #endif } } if (memcmp(bs->sctx->iformat->name,"flv",3)) { ret = avio_seek(bs->sctx->pb, bs->sctx->media_dataoffset, SEEK_SET); if (ret < 0) { av_log(s, AV_LOG_INFO, "avio_seek failed %s---%d \n",__FUNCTION__,__LINE__); return ret; } } bs->cmfvpb = newvpb; fail: if (oldvpb) { cmfvpb_pb_free(oldvpb); } return ret; }
int ff_rm_read_mdpr_codecdata(AVFormatContext *s, AVIOContext *pb, AVStream *st, RMStream *rst, unsigned int codec_data_size, const uint8_t *mime) { unsigned int v; int size; int64_t codec_pos; int ret; if (codec_data_size > INT_MAX) return AVERROR_INVALIDDATA; avpriv_set_pts_info(st, 64, 1, 1000); codec_pos = avio_tell(pb); v = avio_rb32(pb); if (v == MKBETAG('M', 'L', 'T', 'I')) { int number_of_streams = avio_rb16(pb); int number_of_mdpr; int i; for (i = 0; i<number_of_streams; i++) avio_rb16(pb); number_of_mdpr = avio_rb16(pb); if (number_of_mdpr != 1) { avpriv_request_sample(s, "MLTI with multiple MDPR"); } avio_rb32(pb); v = avio_rb32(pb); } if (v == MKTAG(0xfd, 'a', 'r', '.')) { /* ra type header */ if (rm_read_audio_stream_info(s, pb, st, rst, 0)) return -1; } else if (v == MKBETAG('L', 'S', 'D', ':')) { avio_seek(pb, -4, SEEK_CUR); if ((ret = rm_read_extradata(pb, st->codec, codec_data_size)) < 0) return ret; st->codec->codec_type = AVMEDIA_TYPE_AUDIO; st->codec->codec_tag = AV_RL32(st->codec->extradata); st->codec->codec_id = ff_codec_get_id(ff_rm_codec_tags, st->codec->codec_tag); } else if(mime && !strcmp(mime, "logical-fileinfo")){ int stream_count, rule_count, property_count, i; ff_free_stream(s, st); if (avio_rb16(pb) != 0) { av_log(s, AV_LOG_WARNING, "Unsupported version\n"); goto skip; } stream_count = avio_rb16(pb); avio_skip(pb, 6*stream_count); rule_count = avio_rb16(pb); avio_skip(pb, 2*rule_count); property_count = avio_rb16(pb); for(i=0; i<property_count; i++){ uint8_t name[128], val[128]; avio_rb32(pb); if (avio_rb16(pb) != 0) { av_log(s, AV_LOG_WARNING, "Unsupported Name value property version\n"); goto skip; //FIXME skip just this one } get_str8(pb, name, sizeof(name)); switch(avio_rb32(pb)) { case 2: get_strl(pb, val, sizeof(val), avio_rb16(pb)); av_dict_set(&s->metadata, name, val, 0); break; default: avio_skip(pb, avio_rb16(pb)); } } } else { int fps; if (avio_rl32(pb) != MKTAG('V', 'I', 'D', 'O')) { fail1: av_log(s, AV_LOG_WARNING, "Unsupported stream type %08x\n", v); goto skip; } st->codec->codec_tag = avio_rl32(pb); st->codec->codec_id = ff_codec_get_id(ff_rm_codec_tags, st->codec->codec_tag); av_dlog(s, "%X %X\n", st->codec->codec_tag, MKTAG('R', 'V', '2', '0')); if (st->codec->codec_id == AV_CODEC_ID_NONE) goto fail1; st->codec->width = avio_rb16(pb); st->codec->height = avio_rb16(pb); avio_skip(pb, 2); // looks like bits per sample avio_skip(pb, 4); // always zero? st->codec->codec_type = AVMEDIA_TYPE_VIDEO; st->need_parsing = AVSTREAM_PARSE_TIMESTAMPS; fps = avio_rb32(pb); if ((ret = rm_read_extradata(pb, st->codec, codec_data_size - (avio_tell(pb) - codec_pos))) < 0) return ret; if (fps > 0) { av_reduce(&st->avg_frame_rate.den, &st->avg_frame_rate.num, 0x10000, fps, (1 << 30) - 1); #if FF_API_R_FRAME_RATE st->r_frame_rate = st->avg_frame_rate; #endif } else if (s->error_recognition & AV_EF_EXPLODE) { av_log(s, AV_LOG_ERROR, "Invalid framerate\n"); return AVERROR_INVALIDDATA; } } skip: /* skip codec info */ size = avio_tell(pb) - codec_pos; if (codec_data_size >= size) { avio_skip(pb, codec_data_size - size); } else { av_log(s, AV_LOG_WARNING, "codec_data_size %u < size %d\n", codec_data_size, size); } return 0; }
static int ape_read_header(AVFormatContext * s) { AVIOContext *pb = s->pb; APEContext *ape = s->priv_data; AVStream *st; uint32_t tag; int i; int total_blocks, final_size = 0; int64_t pts, file_size; /* Skip any leading junk such as id3v2 tags */ ape->junklength = avio_tell(pb); tag = avio_rl32(pb); if (tag != MKTAG('M', 'A', 'C', ' ')) return -1; ape->fileversion = avio_rl16(pb); if (ape->fileversion < APE_MIN_VERSION || ape->fileversion > APE_MAX_VERSION) { av_log(s, AV_LOG_ERROR, "Unsupported file version - %d.%02d\n", ape->fileversion / 1000, (ape->fileversion % 1000) / 10); return -1; } if (ape->fileversion >= 3980) { ape->padding1 = avio_rl16(pb); ape->descriptorlength = avio_rl32(pb); ape->headerlength = avio_rl32(pb); ape->seektablelength = avio_rl32(pb); ape->wavheaderlength = avio_rl32(pb); ape->audiodatalength = avio_rl32(pb); ape->audiodatalength_high = avio_rl32(pb); ape->wavtaillength = avio_rl32(pb); avio_read(pb, ape->md5, 16); /* Skip any unknown bytes at the end of the descriptor. This is for future compatibility */ if (ape->descriptorlength > 52) avio_skip(pb, ape->descriptorlength - 52); /* Read header data */ ape->compressiontype = avio_rl16(pb); ape->formatflags = avio_rl16(pb); ape->blocksperframe = avio_rl32(pb); ape->finalframeblocks = avio_rl32(pb); ape->totalframes = avio_rl32(pb); ape->bps = avio_rl16(pb); ape->channels = avio_rl16(pb); ape->samplerate = avio_rl32(pb); } else { ape->descriptorlength = 0; ape->headerlength = 32; ape->compressiontype = avio_rl16(pb); ape->formatflags = avio_rl16(pb); ape->channels = avio_rl16(pb); ape->samplerate = avio_rl32(pb); ape->wavheaderlength = avio_rl32(pb); ape->wavtaillength = avio_rl32(pb); ape->totalframes = avio_rl32(pb); ape->finalframeblocks = avio_rl32(pb); if (ape->formatflags & MAC_FORMAT_FLAG_HAS_PEAK_LEVEL) { avio_skip(pb, 4); /* Skip the peak level */ ape->headerlength += 4; } if (ape->formatflags & MAC_FORMAT_FLAG_HAS_SEEK_ELEMENTS) { ape->seektablelength = avio_rl32(pb); ape->headerlength += 4; ape->seektablelength *= sizeof(int32_t); } else ape->seektablelength = ape->totalframes * sizeof(int32_t); if (ape->formatflags & MAC_FORMAT_FLAG_8_BIT) ape->bps = 8; else if (ape->formatflags & MAC_FORMAT_FLAG_24_BIT) ape->bps = 24; else ape->bps = 16; if (ape->fileversion >= 3950) ape->blocksperframe = 73728 * 4; else if (ape->fileversion >= 3900 || (ape->fileversion >= 3800 && ape->compressiontype >= 4000)) ape->blocksperframe = 73728; else ape->blocksperframe = 9216; /* Skip any stored wav header */ if (!(ape->formatflags & MAC_FORMAT_FLAG_CREATE_WAV_HEADER)) avio_skip(pb, ape->wavheaderlength); } if(!ape->totalframes){ av_log(s, AV_LOG_ERROR, "No frames in the file!\n"); return AVERROR(EINVAL); } if(ape->totalframes > UINT_MAX / sizeof(APEFrame)){ av_log(s, AV_LOG_ERROR, "Too many frames: %"PRIu32"\n", ape->totalframes); return -1; } if (ape->seektablelength && (ape->seektablelength / sizeof(*ape->seektable)) < ape->totalframes) { av_log(s, AV_LOG_ERROR, "Number of seek entries is less than number of frames: %zu vs. %"PRIu32"\n", ape->seektablelength / sizeof(*ape->seektable), ape->totalframes); return AVERROR_INVALIDDATA; } ape->frames = av_malloc(ape->totalframes * sizeof(APEFrame)); if(!ape->frames) return AVERROR(ENOMEM); ape->firstframe = ape->junklength + ape->descriptorlength + ape->headerlength + ape->seektablelength + ape->wavheaderlength; ape->currentframe = 0; ape->totalsamples = ape->finalframeblocks; if (ape->totalframes > 1) ape->totalsamples += ape->blocksperframe * (ape->totalframes - 1); if (ape->seektablelength > 0) { ape->seektable = av_malloc(ape->seektablelength); if (!ape->seektable) return AVERROR(ENOMEM); for (i = 0; i < ape->seektablelength / sizeof(uint32_t); i++) ape->seektable[i] = avio_rl32(pb); } ape->frames[0].pos = ape->firstframe; ape->frames[0].nblocks = ape->blocksperframe; ape->frames[0].skip = 0; for (i = 1; i < ape->totalframes; i++) { ape->frames[i].pos = ape->seektable[i] + ape->junklength; ape->frames[i].nblocks = ape->blocksperframe; ape->frames[i - 1].size = ape->frames[i].pos - ape->frames[i - 1].pos; ape->frames[i].skip = (ape->frames[i].pos - ape->frames[0].pos) & 3; } ape->frames[ape->totalframes - 1].nblocks = ape->finalframeblocks; /* calculate final packet size from total file size, if available */ file_size = avio_size(pb); if (file_size > 0) { final_size = file_size - ape->frames[ape->totalframes - 1].pos - ape->wavtaillength; final_size -= final_size & 3; } if (file_size <= 0 || final_size <= 0) final_size = ape->finalframeblocks * 8; ape->frames[ape->totalframes - 1].size = final_size; for (i = 0; i < ape->totalframes; i++) { if(ape->frames[i].skip){ ape->frames[i].pos -= ape->frames[i].skip; ape->frames[i].size += ape->frames[i].skip; } ape->frames[i].size = (ape->frames[i].size + 3) & ~3; } ape_dumpinfo(s, ape); /* try to read APE tags */ if (pb->seekable) { ff_ape_parse_tag(s); avio_seek(pb, 0, SEEK_SET); } av_log(s, AV_LOG_DEBUG, "Decoding file - v%d.%02d, compression level %"PRIu16"\n", ape->fileversion / 1000, (ape->fileversion % 1000) / 10, ape->compressiontype); /* now we are ready: build format streams */ st = avformat_new_stream(s, NULL); if (!st) return -1; total_blocks = (ape->totalframes == 0) ? 0 : ((ape->totalframes - 1) * ape->blocksperframe) + ape->finalframeblocks; st->codec->codec_type = AVMEDIA_TYPE_AUDIO; st->codec->codec_id = CODEC_ID_APE; st->codec->codec_tag = MKTAG('A', 'P', 'E', ' '); st->codec->channels = ape->channels; st->codec->sample_rate = ape->samplerate; st->codec->bits_per_coded_sample = ape->bps; st->nb_frames = ape->totalframes; st->start_time = 0; st->duration = total_blocks / MAC_SUBFRAME_SIZE; avpriv_set_pts_info(st, 64, MAC_SUBFRAME_SIZE, ape->samplerate); st->codec->extradata = av_malloc(APE_EXTRADATA_SIZE); st->codec->extradata_size = APE_EXTRADATA_SIZE; AV_WL16(st->codec->extradata + 0, ape->fileversion); AV_WL16(st->codec->extradata + 2, ape->compressiontype); AV_WL16(st->codec->extradata + 4, ape->formatflags); pts = 0; for (i = 0; i < ape->totalframes; i++) { ape->frames[i].pts = pts; av_add_index_entry(st, ape->frames[i].pos, ape->frames[i].pts, 0, 0, AVINDEX_KEYFRAME); pts += ape->blocksperframe / MAC_SUBFRAME_SIZE; } return 0; }
static int wsvqa_read_header(AVFormatContext *s, AVFormatParameters *ap) { WsVqaDemuxContext *wsvqa = s->priv_data; AVIOContext *pb = s->pb; AVStream *st; unsigned char *header; unsigned char scratch[VQA_PREAMBLE_SIZE]; unsigned int chunk_tag; unsigned int chunk_size; /* initialize the video decoder stream */ st = avformat_new_stream(s, NULL); if (!st) return AVERROR(ENOMEM); avpriv_set_pts_info(st, 33, 1, VQA_FRAMERATE); wsvqa->video_stream_index = st->index; st->codec->codec_type = AVMEDIA_TYPE_VIDEO; st->codec->codec_id = CODEC_ID_WS_VQA; st->codec->codec_tag = 0; /* no fourcc */ /* skip to the start of the VQA header */ avio_seek(pb, 20, SEEK_SET); /* the VQA header needs to go to the decoder */ st->codec->extradata_size = VQA_HEADER_SIZE; st->codec->extradata = av_mallocz(VQA_HEADER_SIZE + FF_INPUT_BUFFER_PADDING_SIZE); header = (unsigned char *)st->codec->extradata; if (avio_read(pb, st->codec->extradata, VQA_HEADER_SIZE) != VQA_HEADER_SIZE) { av_free(st->codec->extradata); return AVERROR(EIO); } st->codec->width = AV_RL16(&header[6]); st->codec->height = AV_RL16(&header[8]); /* initialize the audio decoder stream for VQA v1 or nonzero samplerate */ if (AV_RL16(&header[24]) || (AV_RL16(&header[0]) == 1 && AV_RL16(&header[2]) == 1)) { st = avformat_new_stream(s, NULL); if (!st) return AVERROR(ENOMEM); avpriv_set_pts_info(st, 33, 1, VQA_FRAMERATE); st->codec->codec_type = AVMEDIA_TYPE_AUDIO; if (AV_RL16(&header[0]) == 1) st->codec->codec_id = CODEC_ID_WESTWOOD_SND1; else st->codec->codec_id = CODEC_ID_ADPCM_IMA_WS; st->codec->codec_tag = 0; /* no tag */ st->codec->sample_rate = AV_RL16(&header[24]); if (!st->codec->sample_rate) st->codec->sample_rate = 22050; st->codec->channels = header[26]; if (!st->codec->channels) st->codec->channels = 1; st->codec->bits_per_coded_sample = 16; st->codec->bit_rate = st->codec->channels * st->codec->sample_rate * st->codec->bits_per_coded_sample / 4; st->codec->block_align = st->codec->channels * st->codec->bits_per_coded_sample; wsvqa->audio_stream_index = st->index; wsvqa->audio_samplerate = st->codec->sample_rate; wsvqa->audio_channels = st->codec->channels; wsvqa->audio_frame_counter = 0; } /* there are 0 or more chunks before the FINF chunk; iterate until * FINF has been skipped and the file will be ready to be demuxed */ do { if (avio_read(pb, scratch, VQA_PREAMBLE_SIZE) != VQA_PREAMBLE_SIZE) return AVERROR(EIO); chunk_tag = AV_RB32(&scratch[0]); chunk_size = AV_RB32(&scratch[4]); /* catch any unknown header tags, for curiousity */ switch (chunk_tag) { case CINF_TAG: case CINH_TAG: case CIND_TAG: case PINF_TAG: case PINH_TAG: case PIND_TAG: case FINF_TAG: case CMDS_TAG: break; default: av_log (s, AV_LOG_ERROR, " note: unknown chunk seen (%c%c%c%c)\n", scratch[0], scratch[1], scratch[2], scratch[3]); break; } avio_skip(pb, chunk_size); } while (chunk_tag != FINF_TAG); return 0; }
static int iff_read_header(AVFormatContext *s, AVFormatParameters *ap) { IffDemuxContext *iff = s->priv_data; AVIOContext *pb = s->pb; AVStream *st; uint8_t *buf; uint32_t chunk_id, data_size; uint32_t screenmode = 0; unsigned transparency = 0; unsigned masking = 0; // no mask st = avformat_new_stream(s, NULL); if (!st) return AVERROR(ENOMEM); st->codec->channels = 1; avio_skip(pb, 8); // codec_tag used by ByteRun1 decoder to distinguish progressive (PBM) and interlaced (ILBM) content st->codec->codec_tag = avio_rl32(pb); while(!url_feof(pb)) { uint64_t orig_pos; int res; const char *metadata_tag = NULL; chunk_id = avio_rl32(pb); data_size = avio_rb32(pb); orig_pos = avio_tell(pb); switch(chunk_id) { case ID_VHDR: st->codec->codec_type = AVMEDIA_TYPE_AUDIO; if (data_size < 14) return AVERROR_INVALIDDATA; avio_skip(pb, 12); st->codec->sample_rate = avio_rb16(pb); if (data_size >= 16) { avio_skip(pb, 1); iff->svx8_compression = avio_r8(pb); } break; case ID_ABIT: case ID_BODY: iff->body_pos = avio_tell(pb); iff->body_size = data_size; break; case ID_CHAN: if (data_size < 4) return AVERROR_INVALIDDATA; st->codec->channels = (avio_rb32(pb) < 6) ? 1 : 2; break; case ID_CAMG: if (data_size < 4) return AVERROR_INVALIDDATA; screenmode = avio_rb32(pb); break; case ID_CMAP: st->codec->extradata_size = data_size + IFF_EXTRA_VIDEO_SIZE; st->codec->extradata = av_malloc(data_size + IFF_EXTRA_VIDEO_SIZE + FF_INPUT_BUFFER_PADDING_SIZE); if (!st->codec->extradata) return AVERROR(ENOMEM); if (avio_read(pb, st->codec->extradata + IFF_EXTRA_VIDEO_SIZE, data_size) < 0) return AVERROR(EIO); break; case ID_BMHD: iff->bitmap_compression = -1; st->codec->codec_type = AVMEDIA_TYPE_VIDEO; if (data_size <= 8) return AVERROR_INVALIDDATA; st->codec->width = avio_rb16(pb); st->codec->height = avio_rb16(pb); avio_skip(pb, 4); // x, y offset st->codec->bits_per_coded_sample = avio_r8(pb); if (data_size >= 10) masking = avio_r8(pb); if (data_size >= 11) iff->bitmap_compression = avio_r8(pb); if (data_size >= 14) { avio_skip(pb, 1); // padding transparency = avio_rb16(pb); } if (data_size >= 16) { st->sample_aspect_ratio.num = avio_r8(pb); st->sample_aspect_ratio.den = avio_r8(pb); } break; case ID_ANNO: case ID_TEXT: metadata_tag = "comment"; break; case ID_AUTH: metadata_tag = "artist"; break; case ID_COPYRIGHT: metadata_tag = "copyright"; break; case ID_NAME: metadata_tag = "title"; break; } if (metadata_tag) { if ((res = get_metadata(s, metadata_tag, data_size)) < 0) { av_log(s, AV_LOG_ERROR, "cannot allocate metadata tag %s!", metadata_tag); return res; } } avio_skip(pb, data_size - (avio_tell(pb) - orig_pos) + (data_size & 1)); } avio_seek(pb, iff->body_pos, SEEK_SET); switch(st->codec->codec_type) { case AVMEDIA_TYPE_AUDIO: avpriv_set_pts_info(st, 32, 1, st->codec->sample_rate); switch (iff->svx8_compression) { case COMP_NONE: st->codec->codec_id = CODEC_ID_PCM_S8_PLANAR; break; case COMP_FIB: st->codec->codec_id = CODEC_ID_8SVX_FIB; break; case COMP_EXP: st->codec->codec_id = CODEC_ID_8SVX_EXP; break; default: av_log(s, AV_LOG_ERROR, "Unknown SVX8 compression method '%d'\n", iff->svx8_compression); return -1; } st->codec->bits_per_coded_sample = iff->svx8_compression == COMP_NONE ? 8 : 4; st->codec->bit_rate = st->codec->channels * st->codec->sample_rate * st->codec->bits_per_coded_sample; st->codec->block_align = st->codec->channels * st->codec->bits_per_coded_sample; break; case AVMEDIA_TYPE_VIDEO: iff->bpp = st->codec->bits_per_coded_sample; if ((screenmode & 0x800 /* Hold And Modify */) && iff->bpp <= 8) { iff->ham = iff->bpp > 6 ? 6 : 4; st->codec->bits_per_coded_sample = 24; } iff->flags = (screenmode & 0x80 /* Extra HalfBrite */) && iff->bpp <= 8; iff->masking = masking; iff->transparency = transparency; if (!st->codec->extradata) { st->codec->extradata_size = IFF_EXTRA_VIDEO_SIZE; st->codec->extradata = av_malloc(IFF_EXTRA_VIDEO_SIZE + FF_INPUT_BUFFER_PADDING_SIZE); if (!st->codec->extradata) return AVERROR(ENOMEM); } buf = st->codec->extradata; bytestream_put_be16(&buf, IFF_EXTRA_VIDEO_SIZE); bytestream_put_byte(&buf, iff->bitmap_compression); bytestream_put_byte(&buf, iff->bpp); bytestream_put_byte(&buf, iff->ham); bytestream_put_byte(&buf, iff->flags); bytestream_put_be16(&buf, iff->transparency); bytestream_put_byte(&buf, iff->masking); switch (iff->bitmap_compression) { case BITMAP_RAW: st->codec->codec_id = CODEC_ID_IFF_ILBM; break; case BITMAP_BYTERUN1: st->codec->codec_id = CODEC_ID_IFF_BYTERUN1; break; default: av_log(s, AV_LOG_ERROR, "Unknown bitmap compression method '%d'\n", iff->bitmap_compression); return AVERROR_INVALIDDATA; } break; default: return -1; } return 0; }
int64_t avio_skip(AVIOContext *s, int64_t offset) { return avio_seek(s, offset, SEEK_CUR); }
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 (!url_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: buffer = av_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE); if (!buffer) return AVERROR(ENOMEM); if (avio_read(pb, buffer, size) != size) { av_freep(&buffer); return AVERROR(EIO); } init_get_bits(&gb, buffer, size * 8); break; case TAK_METADATA_MD5: { uint8_t md5[16]; int i; if (size != 19) return AVERROR_INVALIDDATA; avio_read(pb, md5, 16); avio_skip(pb, 3); 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; break; } 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; buffer = NULL; } else if (type == TAK_METADATA_LAST_FRAME) { if (size != 11) return AVERROR_INVALIDDATA; tc->mlast_frame = 1; tc->data_end = get_bits_longlong(&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; }
static int wc3_read_packet(AVFormatContext *s, AVPacket *pkt) { Wc3DemuxContext *wc3 = s->priv_data; AVIOContext *pb = s->pb; unsigned int fourcc_tag; unsigned int size; int packet_read = 0; int ret = 0; unsigned char text[1024]; while (!packet_read) { fourcc_tag = avio_rl32(pb); /* chunk sizes are 16-bit aligned */ size = (avio_rb32(pb) + 1) & (~1); if (avio_feof(pb)) return AVERROR(EIO); switch (fourcc_tag) { case BRCH_TAG: /* no-op */ break; case SHOT_TAG: /* load up new palette */ avio_seek(pb, -8, SEEK_CUR); av_append_packet(pb, &wc3->vpkt, 8 + 4); break; case VGA__TAG: /* send out video chunk */ avio_seek(pb, -8, SEEK_CUR); ret= av_append_packet(pb, &wc3->vpkt, 8 + size); // ignore error if we have some data if (wc3->vpkt.size > 0) ret = 0; *pkt = wc3->vpkt; wc3->vpkt.data = NULL; wc3->vpkt.size = 0; pkt->stream_index = wc3->video_stream_index; pkt->pts = wc3->pts; packet_read = 1; break; case TEXT_TAG: /* subtitle chunk */ if ((unsigned)size > sizeof(text) || (ret = avio_read(pb, text, size)) != size) ret = AVERROR(EIO); else { int i = 0; av_log (s, AV_LOG_DEBUG, "Subtitle time!\n"); if (i >= size || av_strnlen(&text[i + 1], size - i - 1) >= size - i - 1) return AVERROR_INVALIDDATA; av_log (s, AV_LOG_DEBUG, " inglish: %s\n", &text[i + 1]); i += text[i] + 1; if (i >= size || av_strnlen(&text[i + 1], size - i - 1) >= size - i - 1) return AVERROR_INVALIDDATA; av_log (s, AV_LOG_DEBUG, " doytsch: %s\n", &text[i + 1]); i += text[i] + 1; if (i >= size || av_strnlen(&text[i + 1], size - i - 1) >= size - i - 1) return AVERROR_INVALIDDATA; av_log (s, AV_LOG_DEBUG, " fronsay: %s\n", &text[i + 1]); } break; case AUDI_TAG: /* send out audio chunk */ ret= av_get_packet(pb, pkt, size); pkt->stream_index = wc3->audio_stream_index; pkt->pts = wc3->pts; /* time to advance pts */ wc3->pts++; packet_read = 1; break; default: av_log(s, AV_LOG_ERROR, "unrecognized WC3 chunk: %s\n", av_fourcc2str(fourcc_tag)); ret = AVERROR_INVALIDDATA; packet_read = 1; break; } } return ret; }
static int ffm2_read_header(AVFormatContext *s) { FFMContext *ffm = s->priv_data; AVStream *st; AVIOContext *pb = s->pb; AVCodecContext *codec; int ret; int f_main = 0, f_cprv = -1, f_stvi = -1, f_stau = -1; AVCodec *enc; char *buffer; ffm->packet_size = avio_rb32(pb); if (ffm->packet_size != FFM_PACKET_SIZE) { av_log(s, AV_LOG_ERROR, "Invalid packet size %d, expected size was %d\n", ffm->packet_size, FFM_PACKET_SIZE); ret = AVERROR_INVALIDDATA; goto fail; } ffm->write_index = avio_rb64(pb); /* get also filesize */ if (pb->seekable) { ffm->file_size = avio_size(pb); if (ffm->write_index && 0) adjust_write_index(s); } else { ffm->file_size = (UINT64_C(1) << 63) - 1; } while(!avio_feof(pb)) { unsigned id = avio_rb32(pb); unsigned size = avio_rb32(pb); int64_t next = avio_tell(pb) + size; char rc_eq_buf[128]; if(!id) break; switch(id) { case MKBETAG('M', 'A', 'I', 'N'): if (f_main++) { ret = AVERROR(EINVAL); goto fail; } avio_rb32(pb); /* nb_streams */ avio_rb32(pb); /* total bitrate */ break; case MKBETAG('C', 'O', 'M', 'M'): f_cprv = f_stvi = f_stau = 0; st = avformat_new_stream(s, NULL); if (!st) { ret = AVERROR(ENOMEM); goto fail; } avpriv_set_pts_info(st, 64, 1, 1000000); codec = st->codec; /* generic info */ codec->codec_id = avio_rb32(pb); codec->codec_type = avio_r8(pb); codec->bit_rate = avio_rb32(pb); codec->flags = avio_rb32(pb); codec->flags2 = avio_rb32(pb); codec->debug = avio_rb32(pb); if (codec->flags & CODEC_FLAG_GLOBAL_HEADER) { if (ff_get_extradata(codec, pb, avio_rb32(pb)) < 0) return AVERROR(ENOMEM); } break; case MKBETAG('S', 'T', 'V', 'I'): if (f_stvi++) { ret = AVERROR(EINVAL); goto fail; } codec->time_base.num = avio_rb32(pb); codec->time_base.den = avio_rb32(pb); if (codec->time_base.num <= 0 || codec->time_base.den <= 0) { av_log(s, AV_LOG_ERROR, "Invalid time base %d/%d\n", codec->time_base.num, codec->time_base.den); ret = AVERROR_INVALIDDATA; goto fail; } codec->width = avio_rb16(pb); codec->height = avio_rb16(pb); codec->gop_size = avio_rb16(pb); codec->pix_fmt = avio_rb32(pb); codec->qmin = avio_r8(pb); codec->qmax = avio_r8(pb); codec->max_qdiff = avio_r8(pb); codec->qcompress = avio_rb16(pb) / 10000.0; codec->qblur = avio_rb16(pb) / 10000.0; codec->bit_rate_tolerance = avio_rb32(pb); avio_get_str(pb, INT_MAX, rc_eq_buf, sizeof(rc_eq_buf)); codec->rc_eq = av_strdup(rc_eq_buf); codec->rc_max_rate = avio_rb32(pb); codec->rc_min_rate = avio_rb32(pb); codec->rc_buffer_size = avio_rb32(pb); codec->i_quant_factor = av_int2double(avio_rb64(pb)); codec->b_quant_factor = av_int2double(avio_rb64(pb)); codec->i_quant_offset = av_int2double(avio_rb64(pb)); codec->b_quant_offset = av_int2double(avio_rb64(pb)); codec->dct_algo = avio_rb32(pb); codec->strict_std_compliance = avio_rb32(pb); codec->max_b_frames = avio_rb32(pb); codec->mpeg_quant = avio_rb32(pb); codec->intra_dc_precision = avio_rb32(pb); codec->me_method = avio_rb32(pb); codec->mb_decision = avio_rb32(pb); codec->nsse_weight = avio_rb32(pb); codec->frame_skip_cmp = avio_rb32(pb); codec->rc_buffer_aggressivity = av_int2double(avio_rb64(pb)); codec->codec_tag = avio_rb32(pb); codec->thread_count = avio_r8(pb); codec->coder_type = avio_rb32(pb); codec->me_cmp = avio_rb32(pb); codec->me_subpel_quality = avio_rb32(pb); codec->me_range = avio_rb32(pb); codec->keyint_min = avio_rb32(pb); codec->scenechange_threshold = avio_rb32(pb); codec->b_frame_strategy = avio_rb32(pb); codec->qcompress = av_int2double(avio_rb64(pb)); codec->qblur = av_int2double(avio_rb64(pb)); codec->max_qdiff = avio_rb32(pb); codec->refs = avio_rb32(pb); break; case MKBETAG('S', 'T', 'A', 'U'): if (f_stau++) { ret = AVERROR(EINVAL); goto fail; } codec->sample_rate = avio_rb32(pb); codec->channels = avio_rl16(pb); codec->frame_size = avio_rl16(pb); break; case MKBETAG('C', 'P', 'R', 'V'): if (f_cprv++) { ret = AVERROR(EINVAL); goto fail; } enc = avcodec_find_encoder(codec->codec_id); if (enc && enc->priv_data_size && enc->priv_class) { buffer = av_malloc(size + 1); if (!buffer) { ret = AVERROR(ENOMEM); goto fail; } avio_get_str(pb, size, buffer, size + 1); if ((ret = ffm_append_recommended_configuration(st, &buffer)) < 0) goto fail; } break; case MKBETAG('S', '2', 'V', 'I'): if (f_stvi++) { ret = AVERROR(EINVAL); goto fail; } buffer = av_malloc(size); if (!buffer) { ret = AVERROR(ENOMEM); goto fail; } avio_get_str(pb, INT_MAX, buffer, size); av_set_options_string(codec, buffer, "=", ","); if ((ret = ffm_append_recommended_configuration(st, &buffer)) < 0) goto fail; break; case MKBETAG('S', '2', 'A', 'U'): if (f_stau++) { ret = AVERROR(EINVAL); goto fail; } buffer = av_malloc(size); if (!buffer) { ret = AVERROR(ENOMEM); goto fail; } avio_get_str(pb, INT_MAX, buffer, size); av_set_options_string(codec, buffer, "=", ","); if ((ret = ffm_append_recommended_configuration(st, &buffer)) < 0) goto fail; break; } avio_seek(pb, next, SEEK_SET); } /* get until end of block reached */ while ((avio_tell(pb) % ffm->packet_size) != 0 && !pb->eof_reached) avio_r8(pb); /* init packet demux */ ffm->packet_ptr = ffm->packet; ffm->packet_end = ffm->packet; ffm->frame_offset = 0; ffm->dts = 0; ffm->read_state = READ_HEADER; ffm->first_packet = 1; return 0; fail: ffm_close(s); return ret; }