diff options
| author | Tim Redfern <tim@eclectronics.org> | 2013-12-29 12:19:38 +0000 |
|---|---|---|
| committer | Tim Redfern <tim@eclectronics.org> | 2013-12-29 12:19:38 +0000 |
| commit | f7813a5324be39d13ab536c245d15dfc602a7849 (patch) | |
| tree | fad99148b88823d34a5df2f0a25881a002eb291b /ffmpeg/libavformat/asfdec.c | |
| parent | b7a5a477b8ff4d4e3028b9dfb9a9df0a41463f92 (diff) | |
basic type mechanism working
Diffstat (limited to 'ffmpeg/libavformat/asfdec.c')
| -rw-r--r-- | ffmpeg/libavformat/asfdec.c | 107 |
1 files changed, 63 insertions, 44 deletions
diff --git a/ffmpeg/libavformat/asfdec.c b/ffmpeg/libavformat/asfdec.c index 1d7f26c..1f8b25c 100644 --- a/ffmpeg/libavformat/asfdec.c +++ b/ffmpeg/libavformat/asfdec.c @@ -19,14 +19,13 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -//#define DEBUG - #include "libavutil/attributes.h" #include "libavutil/avassert.h" #include "libavutil/avstring.h" #include "libavutil/bswap.h" #include "libavutil/common.h" #include "libavutil/dict.h" +#include "libavutil/internal.h" #include "libavutil/mathematics.h" #include "libavutil/opt.h" #include "avformat.h" @@ -69,7 +68,6 @@ typedef struct { unsigned int packet_frag_size; int64_t packet_frag_timestamp; int packet_multi_size; - int packet_obj_size; int packet_time_delta; int packet_time_start; int64_t packet_pos; @@ -368,14 +366,8 @@ static int asf_read_stream_properties(AVFormatContext *s, int64_t size) if (!st) return AVERROR(ENOMEM); avpriv_set_pts_info(st, 32, 1, 1000); /* 32 bit pts in ms */ - asf_st = av_mallocz(sizeof(ASFStream)); - if (!asf_st) - return AVERROR(ENOMEM); - st->priv_data = asf_st; start_time = asf->hdr.preroll; - asf_st->stream_language_index = 128; // invalid stream index means no language info - if (!(asf->hdr.flags & 0x01)) { // if we aren't streaming... int64_t fsize = avio_size(pb); if (fsize <= 0 || (int64_t)asf->hdr.file_size <= 0 || FFABS(fsize - (int64_t)asf->hdr.file_size) < 10000) @@ -407,6 +399,7 @@ static int asf_read_stream_properties(AVFormatContext *s, int64_t size) st->id = avio_rl16(pb) & 0x7f; /* stream id */ // mapping of asf ID to AV stream ID; asf->asfid2avid[st->id] = s->nb_streams - 1; + asf_st = &asf->streams[st->id]; avio_rl32(pb); @@ -472,6 +465,8 @@ static int asf_read_stream_properties(AVFormatContext *s, int64_t size) st->codec->extradata_size = ffio_limit(pb, sizeX - 40); st->codec->extradata = av_mallocz(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE); + if (!st->codec->extradata) + return AVERROR(ENOMEM); avio_read(pb, st->codec->extradata, st->codec->extradata_size); } @@ -684,6 +679,7 @@ static int asf_read_metadata(AVFormatContext *s, int64_t size) static int asf_read_marker(AVFormatContext *s, int64_t size) { AVIOContext *pb = s->pb; + ASFContext *asf = s->priv_data; int i, count, name_len, ret; char name[1024]; @@ -701,6 +697,7 @@ static int asf_read_marker(AVFormatContext *s, int64_t size) avio_rl64(pb); // offset, 8 bytes pres_time = avio_rl64(pb); // presentation time + pres_time -= asf->hdr.preroll * 10000; avio_rl16(pb); // entry length avio_rl32(pb); // send time avio_rl32(pb); // flags @@ -731,6 +728,10 @@ static int asf_read_header(AVFormatContext *s) avio_r8(pb); avio_r8(pb); memset(&asf->asfid2avid, -1, sizeof(asf->asfid2avid)); + + for (i = 0; i<128; i++) + asf->streams[i].stream_language_index = 128; // invalid stream index means no language info + for (;;) { uint64_t gpos = avio_tell(pb); ff_get_guid(pb, &g); @@ -753,7 +754,9 @@ static int asf_read_header(AVFormatContext *s) if (ret < 0) return ret; } else if (!ff_guidcmp(&g, &ff_asf_stream_header)) { - asf_read_stream_properties(s, gsize); + int ret = asf_read_stream_properties(s, gsize); + if (ret < 0) + return ret; } else if (!ff_guidcmp(&g, &ff_asf_comment_header)) { asf_read_content_desc(s, gsize); } else if (!ff_guidcmp(&g, &ff_asf_language_guid)) { @@ -883,7 +886,7 @@ static int asf_read_header(AVFormatContext *s) * @param pb context to read data from * @return 0 on success, <0 on error */ -static int ff_asf_get_packet(AVFormatContext *s, AVIOContext *pb) +static int asf_get_packet(AVFormatContext *s, AVIOContext *pb) { ASFContext *asf = s->priv_data; uint32_t packet_length, padsize; @@ -1009,10 +1012,10 @@ static int asf_read_frame_header(AVFormatContext *s, AVIOContext *pb) if (asf->packet_replic_size >= 8) { int64_t end = avio_tell(pb) + asf->packet_replic_size; AVRational aspect; - asf->packet_obj_size = avio_rl32(pb); - if (asf->packet_obj_size >= (1 << 24) || asf->packet_obj_size <= 0) { + asfst->packet_obj_size = avio_rl32(pb); + if (asfst->packet_obj_size >= (1 << 24) || asfst->packet_obj_size <= 0) { av_log(s, AV_LOG_ERROR, "packet_obj_size invalid\n"); - asf->packet_obj_size = 0; + asfst->packet_obj_size = 0; return AVERROR_INVALIDDATA; } asf->packet_frag_timestamp = avio_rl32(pb); // timestamp @@ -1110,7 +1113,7 @@ static int asf_read_frame_header(AVFormatContext *s, AVIOContext *pb) * @return 0 if data was stored in pkt, <0 on error or 1 if more ASF * packets need to be loaded (through asf_get_packet()) */ -static int ff_asf_parse_packet(AVFormatContext *s, AVIOContext *pb, AVPacket *pkt) +static int asf_parse_packet(AVFormatContext *s, AVIOContext *pb, AVPacket *pkt) { ASFContext *asf = s->priv_data; ASFStream *asf_st = 0; @@ -1119,8 +1122,7 @@ static int ff_asf_parse_packet(AVFormatContext *s, AVIOContext *pb, AVPacket *pk if (url_feof(pb)) return AVERROR_EOF; - if (asf->packet_size_left < FRAME_HEADER_SIZE || - asf->packet_segments < 1) { + if (asf->packet_size_left < FRAME_HEADER_SIZE) { int ret = asf->packet_size_left + asf->packet_padsize; assert(ret >= 0); @@ -1135,13 +1137,13 @@ static int ff_asf_parse_packet(AVFormatContext *s, AVIOContext *pb, AVPacket *pk } if (asf->packet_time_start == 0) { if (asf_read_frame_header(s, pb) < 0) { - asf->packet_segments = 0; + asf->packet_time_start = asf->packet_segments = 0; continue; } if (asf->stream_index < 0 || s->streams[asf->stream_index]->discard >= AVDISCARD_ALL || (!asf->packet_key_frame && - s->streams[asf->stream_index]->discard >= AVDISCARD_NONKEY)) { + (s->streams[asf->stream_index]->discard >= AVDISCARD_NONKEY || asf->streams[s->streams[asf->stream_index]->id].skip_to_key))) { asf->packet_time_start = 0; /* unhandled packet (should not happen) */ avio_skip(pb, asf->packet_frag_size); @@ -1151,7 +1153,8 @@ static int ff_asf_parse_packet(AVFormatContext *s, AVIOContext *pb, AVPacket *pk asf->packet_frag_size); continue; } - asf->asf_st = s->streams[asf->stream_index]->priv_data; + asf->asf_st = &asf->streams[s->streams[asf->stream_index]->id]; + asf->asf_st->skip_to_key = 0; } asf_st = asf->asf_st; av_assert0(asf_st); @@ -1160,41 +1163,35 @@ static int ff_asf_parse_packet(AVFormatContext *s, AVIOContext *pb, AVPacket *pk // frag_offset is here used as the beginning timestamp asf->packet_frag_timestamp = asf->packet_time_start; asf->packet_time_start += asf->packet_time_delta; - asf->packet_obj_size = asf->packet_frag_size = avio_r8(pb); + asf_st->packet_obj_size = asf->packet_frag_size = avio_r8(pb); asf->packet_size_left--; asf->packet_multi_size--; - if (asf->packet_multi_size < asf->packet_obj_size) { + if (asf->packet_multi_size < asf_st->packet_obj_size) { asf->packet_time_start = 0; avio_skip(pb, asf->packet_multi_size); asf->packet_size_left -= asf->packet_multi_size; continue; } - asf->packet_multi_size -= asf->packet_obj_size; - } - if (asf_st->frag_offset + asf->packet_frag_size <= asf_st->pkt.size && - asf_st->frag_offset + asf->packet_frag_size > asf->packet_obj_size) { - av_log(s, AV_LOG_INFO, "ignoring invalid packet_obj_size (%d %d %d %d)\n", - asf_st->frag_offset, asf->packet_frag_size, - asf->packet_obj_size, asf_st->pkt.size); - asf->packet_obj_size = asf_st->pkt.size; + asf->packet_multi_size -= asf_st->packet_obj_size; } - if (asf_st->pkt.size != asf->packet_obj_size || + if (asf_st->pkt.size != asf_st->packet_obj_size || // FIXME is this condition sufficient? asf_st->frag_offset + asf->packet_frag_size > asf_st->pkt.size) { if (asf_st->pkt.data) { av_log(s, AV_LOG_INFO, "freeing incomplete packet size %d, new %d\n", - asf_st->pkt.size, asf->packet_obj_size); + asf_st->pkt.size, asf_st->packet_obj_size); asf_st->frag_offset = 0; av_free_packet(&asf_st->pkt); } /* new packet */ - av_new_packet(&asf_st->pkt, asf->packet_obj_size); + av_new_packet(&asf_st->pkt, asf_st->packet_obj_size); asf_st->seq = asf->packet_seq; asf_st->pkt.dts = asf->packet_frag_timestamp - asf->hdr.preroll; asf_st->pkt.stream_index = asf->stream_index; asf_st->pkt.pos = asf_st->packet_pos = asf->packet_pos; + asf_st->pkt_clean = 0; if (asf_st->pkt.data && asf_st->palette_changed) { uint8_t *pal; @@ -1211,7 +1208,7 @@ static int ff_asf_parse_packet(AVFormatContext *s, AVIOContext *pb, AVPacket *pk asf->stream_index, asf->packet_key_frame, asf_st->pkt.flags & AV_PKT_FLAG_KEY, s->streams[asf->stream_index]->codec->codec_type == AVMEDIA_TYPE_AUDIO, - asf->packet_obj_size); + asf_st->packet_obj_size); if (s->streams[asf->stream_index]->codec->codec_type == AVMEDIA_TYPE_AUDIO) asf->packet_key_frame = 1; if (asf->packet_key_frame) @@ -1235,6 +1232,11 @@ static int ff_asf_parse_packet(AVFormatContext *s, AVIOContext *pb, AVPacket *pk continue; } + if (asf->packet_frag_offset != asf_st->frag_offset && !asf_st->pkt_clean) { + memset(asf_st->pkt.data + asf_st->frag_offset, 0, asf_st->pkt.size - asf_st->frag_offset); + asf_st->pkt_clean = 1; + } + ret = avio_read(pb, asf_st->pkt.data + asf->packet_frag_offset, asf->packet_frag_size); if (ret != asf->packet_frag_size) { @@ -1310,7 +1312,9 @@ static int ff_asf_parse_packet(AVFormatContext *s, AVIOContext *pb, AVPacket *pk asf_st->frag_offset = 0; *pkt = asf_st->pkt; #if FF_API_DESTRUCT_PACKET +FF_DISABLE_DEPRECATION_WARNINGS asf_st->pkt.destruct = NULL; +FF_ENABLE_DEPRECATION_WARNINGS #endif asf_st->pkt.buf = 0; asf_st->pkt.size = 0; @@ -1331,9 +1335,9 @@ static int asf_read_packet(AVFormatContext *s, AVPacket *pkt) int ret; /* parse cached packets, if any */ - if ((ret = ff_asf_parse_packet(s, s->pb, pkt)) <= 0) + if ((ret = asf_parse_packet(s, s->pb, pkt)) <= 0) return ret; - if ((ret = ff_asf_get_packet(s, s->pb)) < 0) + if ((ret = asf_get_packet(s, s->pb)) < 0) assert(asf->packet_size_left < FRAME_HEADER_SIZE || asf->packet_segments < 1); asf->packet_time_start = 0; @@ -1350,7 +1354,6 @@ static void asf_reset_header(AVFormatContext *s) int i; asf->packet_size_left = 0; - asf->packet_segments = 0; asf->packet_flags = 0; asf->packet_property = 0; asf->packet_timestamp = 0; @@ -1364,21 +1367,34 @@ static void asf_reset_header(AVFormatContext *s) asf->packet_frag_size = 0; asf->packet_frag_timestamp = 0; asf->packet_multi_size = 0; - asf->packet_obj_size = 0; asf->packet_time_delta = 0; asf->packet_time_start = 0; - for (i = 0; i < s->nb_streams; i++) { - asf_st = s->streams[i]->priv_data; - if (!asf_st) - continue; + for (i = 0; i < 128; i++) { + asf_st = &asf->streams[i]; av_free_packet(&asf_st->pkt); + asf_st->packet_obj_size = 0; asf_st->frag_offset = 0; asf_st->seq = 0; } asf->asf_st = NULL; } +static void skip_to_key(AVFormatContext *s) +{ + ASFContext *asf = s->priv_data; + int i; + + for (i = 0; i < 128; i++) { + int j = asf->asfid2avid[i]; + ASFStream *asf_st = &asf->streams[i]; + if (j < 0 || s->streams[j]->codec->codec_type != AVMEDIA_TYPE_VIDEO) + continue; + + asf_st->skip_to_key = 1; + } +} + static int asf_read_close(AVFormatContext *s) { asf_reset_header(s); @@ -1389,6 +1405,7 @@ static int asf_read_close(AVFormatContext *s) static int64_t asf_read_pts(AVFormatContext *s, int stream_index, int64_t *ppos, int64_t pos_limit) { + ASFContext *asf = s->priv_data; AVPacket pkt1, *pkt = &pkt1; ASFStream *asf_st; int64_t pts; @@ -1407,6 +1424,7 @@ static int64_t asf_read_pts(AVFormatContext *s, int stream_index, if (avio_seek(s->pb, pos, SEEK_SET) < 0) return AV_NOPTS_VALUE; + ff_read_frame_flush(s); asf_reset_header(s); for (;;) { if (av_read_frame(s, pkt) < 0) { @@ -1420,8 +1438,7 @@ static int64_t asf_read_pts(AVFormatContext *s, int stream_index, if (pkt->flags & AV_PKT_FLAG_KEY) { i = pkt->stream_index; - asf_st = s->streams[i]->priv_data; - av_assert0(asf_st); + asf_st = &asf->streams[s->streams[i]->id]; // assert((asf_st->packet_pos - s->data_offset) % s->packet_size == 0); pos = asf_st->packet_pos; @@ -1528,6 +1545,7 @@ static int asf_read_seek(AVFormatContext *s, int stream_index, if(avio_seek(s->pb, pos, SEEK_SET) < 0) return -1; asf_reset_header(s); + skip_to_key(s); return 0; } } @@ -1535,6 +1553,7 @@ static int asf_read_seek(AVFormatContext *s, int stream_index, if (ff_seek_frame_binary(s, stream_index, pts, flags) < 0) return -1; asf_reset_header(s); + skip_to_key(s); return 0; } |
