X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavformat%2Fasfdec.c;h=f3978f08a49e1235149e1fa342de0c665a6801d3;hb=f542dedf72091af8e6f32a12bd64289c58857c21;hp=51422ea13706f9763d9286a0989cfd92421fb232;hpb=84b721db366c0734fdfd23c8daaa7da7da21f761;p=ffmpeg diff --git a/libavformat/asfdec.c b/libavformat/asfdec.c index 51422ea1370..f3978f08a49 100644 --- a/libavformat/asfdec.c +++ b/libavformat/asfdec.c @@ -19,13 +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" @@ -151,12 +151,6 @@ static void print_guid(ff_asf_guid *g) #define print_guid(g) #endif -void ff_get_guid(AVIOContext *s, ff_asf_guid *g) -{ - assert(sizeof(*g) == 16); - avio_read(s, *g, sizeof(*g)); -} - static int asf_probe(AVProbeData *pd) { /* check file header */ @@ -193,7 +187,6 @@ static int asf_read_picture(AVFormatContext *s, int len) enum AVCodecID id = AV_CODEC_ID_NONE; char mimetype[64]; uint8_t *desc = NULL; - ASFStream *ast = NULL; AVStream *st = NULL; int ret, type, picsize, desc_len; @@ -248,12 +241,10 @@ static int asf_read_picture(AVFormatContext *s, int len) goto fail; st = avformat_new_stream(s, NULL); - ast = av_mallocz(sizeof(*ast)); - if (!st || !ast) { + if (!st) { ret = AVERROR(ENOMEM); goto fail; } - st->priv_data = ast; st->disposition |= AV_DISPOSITION_ATTACHED_PIC; st->codec->codec_type = AVMEDIA_TYPE_VIDEO; st->codec->codec_id = id; @@ -271,12 +262,21 @@ static int asf_read_picture(AVFormatContext *s, int len) return 0; fail: - av_freep(&ast); av_freep(&desc); av_free_packet(&pkt); return ret; } +static void get_id3_tag(AVFormatContext *s, int len) +{ + ID3v2ExtraMeta *id3v2_extra_meta = NULL; + + ff_id3v2_read(s, ID3v2_DEFAULT_MAGIC, &id3v2_extra_meta); + if (id3v2_extra_meta) + ff_id3v2_parse_apic(s, &id3v2_extra_meta); + ff_id3v2_free_extra_meta(&id3v2_extra_meta); +} + static void get_tag(AVFormatContext *s, const char *key, int type, int len, int type2_size) { char *value; @@ -291,12 +291,18 @@ static void get_tag(AVFormatContext *s, const char *key, int type, int len, int if (type == 0) { // UTF16-LE avio_get_str16le(s->pb, len, value, 2 * len + 1); + } else if (type == 1) { // byte array + if (!strcmp(key, "WM/Picture")) { // handle cover art + asf_read_picture(s, len); + } else if (!strcmp(key, "ID3")) { // handle ID3 tag + get_id3_tag(s, len); + } else { + av_log(s, AV_LOG_VERBOSE, "Unsupported byte array in tag %s.\n", key); + } + goto finish; } else if (type > 1 && type <= 5) { // boolean or DWORD or QWORD or WORD uint64_t num = get_value(s->pb, type, type2_size); snprintf(value, len, "%"PRIu64, num); - } else if (type == 1 && !strcmp(key, "WM/Picture")) { // handle cover art - asf_read_picture(s, len); - goto finish; } else if (type == 6) { // (don't) handle GUID av_log(s, AV_LOG_DEBUG, "Unsupported GUID value in tag %s.\n", key); goto finish; @@ -854,7 +860,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; @@ -1046,7 +1052,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; @@ -1091,6 +1097,7 @@ static int ff_asf_parse_packet(AVFormatContext *s, AVIOContext *pb, AVPacket *pk asf->asf_st = s->streams[asf->stream_index]->priv_data; } asf_st = asf->asf_st; + av_assert0(asf_st); if (asf->packet_replic_size == 1) { // frag_offset is here used as the beginning timestamp @@ -1218,9 +1225,10 @@ static int ff_asf_parse_packet(AVFormatContext *s, AVIOContext *pb, AVPacket *pk asf_st->ds_span); } else { /* packet descrambling */ - uint8_t *newdata = av_malloc(asf_st->pkt.size + - FF_INPUT_BUFFER_PADDING_SIZE); - if (newdata) { + AVBufferRef *buf = av_buffer_alloc(asf_st->pkt.size + + FF_INPUT_BUFFER_PADDING_SIZE); + if (buf) { + uint8_t *newdata = buf->data; int offset = 0; memset(newdata + asf_st->pkt.size, 0, FF_INPUT_BUFFER_PADDING_SIZE); @@ -1236,13 +1244,20 @@ static int ff_asf_parse_packet(AVFormatContext *s, AVIOContext *pb, AVPacket *pk asf_st->ds_chunk_size); offset += asf_st->ds_chunk_size; } - av_free(asf_st->pkt.data); - asf_st->pkt.data = newdata; + av_buffer_unref(&asf_st->pkt.buf); + asf_st->pkt.buf = buf; + asf_st->pkt.data = buf->data; } } } 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; asf_st->pkt.data = 0; asf_st->pkt.side_data_elems = 0; @@ -1261,9 +1276,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; @@ -1300,6 +1315,8 @@ static void asf_reset_header(AVFormatContext *s) for (i = 0; i < s->nb_streams; i++) { asf_st = s->streams[i]->priv_data; + if (!asf_st) + continue; av_free_packet(&asf_st->pkt); asf_st->frag_offset = 0; asf_st->seq = 0; @@ -1348,6 +1365,7 @@ static int64_t asf_read_pts(AVFormatContext *s, int stream_index, i = pkt->stream_index; asf_st = s->streams[i]->priv_data; + av_assert0(asf_st); // assert((asf_st->packet_pos - s->data_offset) % s->packet_size == 0); pos = asf_st->packet_pos;