From da18e918a4ec015dd0aef1c7ec9cab09f3a019bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Thu, 11 Oct 2012 15:27:25 +0300 Subject: [PATCH 1/4] md5: Allocate a normal private context for the opaque md5 context pointer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This avoids having to overestimate the md5 context size, which isn't known beforehand, allowing us to use the new allocate functions instead. Signed-off-by: Martin Storsjö --- libavformat/md5enc.c | 55 +++++++++++++++++++++++++++++------------- libavformat/md5proto.c | 24 +++++++++++------- 2 files changed, 53 insertions(+), 26 deletions(-) diff --git a/libavformat/md5enc.c b/libavformat/md5enc.c index fbd4d99397..16412c9a34 100644 --- a/libavformat/md5enc.c +++ b/libavformat/md5enc.c @@ -23,13 +23,16 @@ #include "avformat.h" #include "internal.h" -#define PRIVSIZE 512 +struct MD5Context { + struct AVMD5 *md5; +}; static void md5_finish(struct AVFormatContext *s, char *buf) { + struct MD5Context *c = s->priv_data; uint8_t md5[16]; int i, offset = strlen(buf); - av_md5_final(s->priv_data, md5); + av_md5_final(c->md5, md5); for (i = 0; i < sizeof(md5); i++) { snprintf(buf + offset, 3, "%02"PRIx8, md5[i]); offset += 2; @@ -44,25 +47,29 @@ static void md5_finish(struct AVFormatContext *s, char *buf) #if CONFIG_MD5_MUXER static int write_header(struct AVFormatContext *s) { - if (PRIVSIZE < av_md5_size) { - av_log(s, AV_LOG_ERROR, "Insuffient size for md5 context\n"); - return -1; - } - av_md5_init(s->priv_data); + struct MD5Context *c = s->priv_data; + c->md5 = av_md5_alloc(); + if (!c->md5) + return AVERROR(ENOMEM); + av_md5_init(c->md5); return 0; } static int write_packet(struct AVFormatContext *s, AVPacket *pkt) { - av_md5_update(s->priv_data, pkt->data, pkt->size); + struct MD5Context *c = s->priv_data; + av_md5_update(c->md5, pkt->data, pkt->size); return 0; } static int write_trailer(struct AVFormatContext *s) { + struct MD5Context *c = s->priv_data; char buf[64] = "MD5="; md5_finish(s, buf); + + av_freep(&c->md5); return 0; } @@ -70,7 +77,7 @@ AVOutputFormat ff_md5_muxer = { .name = "md5", .long_name = NULL_IF_CONFIG_SMALL("MD5 testing"), .extensions = "", - .priv_data_size = PRIVSIZE, + .priv_data_size = sizeof(struct MD5Context), .audio_codec = AV_CODEC_ID_PCM_S16LE, .video_codec = AV_CODEC_ID_RAWVIDEO, .write_header = write_header, @@ -81,15 +88,21 @@ AVOutputFormat ff_md5_muxer = { #endif #if CONFIG_FRAMEMD5_MUXER +static int framemd5_write_header(struct AVFormatContext *s) +{ + struct MD5Context *c = s->priv_data; + c->md5 = av_md5_alloc(); + if (!c->md5) + return AVERROR(ENOMEM); + return ff_framehash_write_header(s); +} + static int framemd5_write_packet(struct AVFormatContext *s, AVPacket *pkt) { + struct MD5Context *c = s->priv_data; char buf[256]; - if (PRIVSIZE < av_md5_size) { - av_log(s, AV_LOG_ERROR, "Insuffient size for md5 context\n"); - return -1; - } - av_md5_init(s->priv_data); - av_md5_update(s->priv_data, pkt->data, pkt->size); + av_md5_init(c->md5); + av_md5_update(c->md5, pkt->data, pkt->size); snprintf(buf, sizeof(buf) - 64, "%d, %10"PRId64", %10"PRId64", %8d, %8d, ", pkt->stream_index, pkt->dts, pkt->pts, pkt->duration, pkt->size); @@ -97,15 +110,23 @@ static int framemd5_write_packet(struct AVFormatContext *s, AVPacket *pkt) return 0; } +static int framemd5_write_trailer(struct AVFormatContext *s) +{ + struct MD5Context *c = s->priv_data; + av_freep(&c->md5); + return 0; +} + AVOutputFormat ff_framemd5_muxer = { .name = "framemd5", .long_name = NULL_IF_CONFIG_SMALL("Per-frame MD5 testing"), .extensions = "", - .priv_data_size = PRIVSIZE, + .priv_data_size = sizeof(struct MD5Context), .audio_codec = AV_CODEC_ID_PCM_S16LE, .video_codec = AV_CODEC_ID_RAWVIDEO, - .write_header = ff_framehash_write_header, + .write_header = framemd5_write_header, .write_packet = framemd5_write_packet, + .write_trailer = framemd5_write_trailer, .flags = AVFMT_VARIABLE_FPS | AVFMT_TS_NONSTRICT, }; #endif diff --git a/libavformat/md5proto.c b/libavformat/md5proto.c index 796b4ea682..12ddde3d8c 100644 --- a/libavformat/md5proto.c +++ b/libavformat/md5proto.c @@ -27,37 +27,41 @@ #include "avio.h" #include "url.h" -#define PRIV_SIZE 128 +struct MD5Context { + struct AVMD5 *md5; +}; static int md5_open(URLContext *h, const char *filename, int flags) { - if (PRIV_SIZE < av_md5_size) { - av_log(NULL, AV_LOG_ERROR, "Insuffient size for MD5 context\n"); - return -1; - } + struct MD5Context *c = h->priv_data; if (!(flags & AVIO_FLAG_WRITE)) return AVERROR(EINVAL); - av_md5_init(h->priv_data); + c->md5 = av_md5_alloc(); + if (!c->md5) + return AVERROR(ENOMEM); + av_md5_init(c->md5); return 0; } static int md5_write(URLContext *h, const unsigned char *buf, int size) { - av_md5_update(h->priv_data, buf, size); + struct MD5Context *c = h->priv_data; + av_md5_update(c->md5, buf, size); return size; } static int md5_close(URLContext *h) { + struct MD5Context *c = h->priv_data; const char *filename = h->filename; uint8_t md5[16], buf[64]; URLContext *out; int i, err = 0; - av_md5_final(h->priv_data, md5); + av_md5_final(c->md5, md5); for (i = 0; i < sizeof(md5); i++) snprintf(buf + i*2, 3, "%02x", md5[i]); buf[i*2] = '\n'; @@ -76,6 +80,8 @@ static int md5_close(URLContext *h) err = AVERROR(errno); } + av_freep(&c->md5); + return err; } @@ -85,5 +91,5 @@ URLProtocol ff_md5_protocol = { .url_open = md5_open, .url_write = md5_write, .url_close = md5_close, - .priv_data_size = PRIV_SIZE, + .priv_data_size = sizeof(struct MD5Context), }; From fdd666094d42f46935a86ad8375cec67c540bf38 Mon Sep 17 00:00:00 2001 From: Mans Rullgard Date: Thu, 11 Oct 2012 12:33:38 +0100 Subject: [PATCH 2/4] build: add support for Tru64 (OSF/1) Signed-off-by: Mans Rullgard --- configure | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/configure b/configure index 67f88eb0fd..bc3a2180e9 100755 --- a/configure +++ b/configure @@ -2873,6 +2873,10 @@ case $target_os in -l:drtaeabi.dso -l:scppnwdl.dso -lsupc++ -lgcc \ -l:libc.dso -l:libm.dso -l:euser.dso -l:libcrt0.lib ;; + osf1) + add_cppflags -D_OSF_SOURCE -D_POSIX_PII -D_REENTRANT + AVSERVERLDFLAGS= + ;; none) ;; *) From d2fcb356caf38c12b0fc9d8c5bac592a28b0f0f1 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sat, 6 Oct 2012 12:36:38 +0200 Subject: [PATCH 3/4] pixdesc: add functions for accessing pixel format descriptors. Make av_pix_fmt_descriptors table static on next major bump. Making the table public is dangerous, since the caller has no way to know how large it actually is. It also prevents adding new fields to AVPixFmtDescriptor without a major bump. --- doc/APIchanges | 5 +++++ libavutil/pixdesc.c | 30 ++++++++++++++++++++++++++++++ libavutil/pixdesc.h | 23 +++++++++++++++++++++++ libavutil/version.h | 5 ++++- 4 files changed, 62 insertions(+), 1 deletion(-) diff --git a/doc/APIchanges b/doc/APIchanges index 81a2266acb..0c9a455838 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -13,6 +13,11 @@ libavutil: 2011-04-18 API changes, most recent first: +2012-10-12 - xxxxxxx - lavu 51.44.0 - pixdesc.h + Add functions for accessing pixel format descriptors. + Accessing the av_pix_fmt_descriptors array directly is now + deprecated. + 2012-10-xx - xxxxxxx - lavu 51.43.0 - aes.h, md5.h, sha.h, tree.h Add functions for allocating the opaque contexts for the algorithms, deprecate the context size variables. diff --git a/libavutil/pixdesc.c b/libavutil/pixdesc.c index f5098a7320..3a1f9fe957 100644 --- a/libavutil/pixdesc.c +++ b/libavutil/pixdesc.c @@ -21,6 +21,8 @@ #include #include + +#include "common.h" #include "pixfmt.h" #include "pixdesc.h" @@ -122,6 +124,9 @@ void av_write_image_line(const uint16_t *src, } } +#if !FF_API_PIX_FMT_DESC +static +#endif const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = { [AV_PIX_FMT_YUV420P] = { .name = "yuv420p", @@ -1164,3 +1169,28 @@ char *av_get_pix_fmt_string (char *buf, int buf_size, enum AVPixelFormat pix_fmt return buf; } + +const AVPixFmtDescriptor *av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt) +{ + if (pix_fmt < 0 || pix_fmt >= AV_PIX_FMT_NB) + return NULL; + return &av_pix_fmt_descriptors[pix_fmt]; +} + +const AVPixFmtDescriptor *av_pix_fmt_desc_next(const AVPixFmtDescriptor *prev) +{ + if (!prev) + return &av_pix_fmt_descriptors[0]; + if (prev - av_pix_fmt_descriptors < FF_ARRAY_ELEMS(av_pix_fmt_descriptors) - 1) + return prev + 1; + return NULL; +} + +enum AVPixelFormat av_pix_fmt_desc_get_id(const AVPixFmtDescriptor *desc) +{ + if (desc < av_pix_fmt_descriptors || + desc >= av_pix_fmt_descriptors + FF_ARRAY_ELEMS(av_pix_fmt_descriptors)) + return AV_PIX_FMT_NONE; + + return desc - av_pix_fmt_descriptors; +} diff --git a/libavutil/pixdesc.h b/libavutil/pixdesc.h index 31ddd2e378..7da17bcf12 100644 --- a/libavutil/pixdesc.h +++ b/libavutil/pixdesc.h @@ -96,10 +96,12 @@ typedef struct AVPixFmtDescriptor{ */ #define PIX_FMT_PSEUDOPAL 64 +#if FF_API_PIX_FMT_DESC /** * The array of all the pixel format descriptors. */ extern const AVPixFmtDescriptor av_pix_fmt_descriptors[]; +#endif /** * Read a line from an image, and write the values of the @@ -180,4 +182,25 @@ char *av_get_pix_fmt_string (char *buf, int buf_size, enum AVPixelFormat pix_fmt */ int av_get_bits_per_pixel(const AVPixFmtDescriptor *pixdesc); +/** + * @return a pixel format descriptor for provided pixel format or NULL if + * this pixel format is unknown. + */ +const AVPixFmtDescriptor *av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt); + +/** + * Iterate over all pixel format descriptors known to libavutil. + * + * @param prev previous descriptor. NULL to get the first descriptor. + * + * @return next descriptor or NULL after the last descriptor + */ +const AVPixFmtDescriptor *av_pix_fmt_desc_next(const AVPixFmtDescriptor *prev); + +/** + * @return an AVPixelFormat id described by desc, or AV_PIX_FMT_NONE if desc + * is not a valid pointer to a pixel format descriptor. + */ +enum AVPixelFormat av_pix_fmt_desc_get_id(const AVPixFmtDescriptor *desc); + #endif /* AVUTIL_PIXDESC_H */ diff --git a/libavutil/version.h b/libavutil/version.h index 856283598d..d4b764ae15 100644 --- a/libavutil/version.h +++ b/libavutil/version.h @@ -37,7 +37,7 @@ */ #define LIBAVUTIL_VERSION_MAJOR 51 -#define LIBAVUTIL_VERSION_MINOR 43 +#define LIBAVUTIL_VERSION_MINOR 44 #define LIBAVUTIL_VERSION_MICRO 0 #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ @@ -79,6 +79,9 @@ #ifndef FF_API_CONTEXT_SIZE #define FF_API_CONTEXT_SIZE (LIBAVUTIL_VERSION_MAJOR < 52) #endif +#ifndef FF_API_PIX_FMT_DESC +#define FF_API_PIX_FMT_DESC (LIBAVUTIL_VERSION_MAJOR < 52) +#endif /** * @} From b7f1010c8fce09096057528f7cd29589ea1ae7df Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sat, 6 Oct 2012 13:29:37 +0200 Subject: [PATCH 4/4] tools: do not use av_pix_fmt_descriptors directly. --- avprobe.c | 6 +++--- cmdutils.c | 16 +++++++++++----- tools/graph2dot.c | 4 ++-- 3 files changed, 16 insertions(+), 10 deletions(-) diff --git a/avprobe.c b/avprobe.c index 16a5d29ebb..3a3ae0fa7d 100644 --- a/avprobe.c +++ b/avprobe.c @@ -584,6 +584,7 @@ static void show_stream(AVFormatContext *fmt_ctx, int stream_idx) const char *profile; char val_str[128]; AVRational display_aspect_ratio; + const AVPixFmtDescriptor *desc; probe_object_header("stream"); @@ -629,9 +630,8 @@ static void show_stream(AVFormatContext *fmt_ctx, int stream_idx) rational_string(val_str, sizeof(val_str), ":", &display_aspect_ratio)); } - probe_str("pix_fmt", - dec_ctx->pix_fmt != AV_PIX_FMT_NONE ? - av_pix_fmt_descriptors[dec_ctx->pix_fmt].name : "unknown"); + desc = av_pix_fmt_desc_get(dec_ctx->pix_fmt); + probe_str("pix_fmt", desc ? desc->name : "unknown"); probe_int("level", dec_ctx->level); break; diff --git a/cmdutils.c b/cmdutils.c index ac971df20a..34c52ca136 100644 --- a/cmdutils.c +++ b/cmdutils.c @@ -866,7 +866,7 @@ int show_filters(void *optctx, const char *opt, const char *arg) int show_pix_fmts(void *optctx, const char *opt, const char *arg) { - enum AVPixelFormat pix_fmt; + const AVPixFmtDescriptor *pix_desc = NULL; printf("Pixel formats:\n" "I.... = Supported Input format for conversion\n" @@ -882,8 +882,8 @@ int show_pix_fmts(void *optctx, const char *opt, const char *arg) # define sws_isSupportedOutput(x) 0 #endif - for (pix_fmt = 0; pix_fmt < AV_PIX_FMT_NB; pix_fmt++) { - const AVPixFmtDescriptor *pix_desc = &av_pix_fmt_descriptors[pix_fmt]; + while ((pix_desc = av_pix_fmt_desc_next(pix_desc))) { + enum AVPixelFormat pix_fmt = av_pix_fmt_desc_get_id(pix_desc); printf("%c%c%c%c%c %-16s %d %2d\n", sws_isSupportedInput (pix_fmt) ? 'I' : '.', sws_isSupportedOutput(pix_fmt) ? 'O' : '.', @@ -1282,13 +1282,19 @@ void *grow_array(void *array, int elem_size, int *size, int new_size) static int alloc_buffer(FrameBuffer **pool, AVCodecContext *s, FrameBuffer **pbuf) { - FrameBuffer *buf = av_mallocz(sizeof(*buf)); + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(s->pix_fmt); + FrameBuffer *buf; int i, ret; - const int pixel_size = av_pix_fmt_descriptors[s->pix_fmt].comp[0].step_minus1+1; + int pixel_size; int h_chroma_shift, v_chroma_shift; int edge = 32; // XXX should be avcodec_get_edge_width(), but that fails on svq1 int w = s->width, h = s->height; + if (!desc) + return AVERROR(EINVAL); + pixel_size = desc->comp[0].step_minus1 + 1; + + buf = av_mallocz(sizeof(*buf)); if (!buf) return AVERROR(ENOMEM); diff --git a/tools/graph2dot.c b/tools/graph2dot.c index e7f487d146..c0142ccd31 100644 --- a/tools/graph2dot.c +++ b/tools/graph2dot.c @@ -80,10 +80,10 @@ static void print_digraph(FILE *outfile, AVFilterGraph *graph) fprintf(outfile, "\"%s\" -> \"%s\"", filter_ctx_label, dst_filter_ctx_label); if (link->type == AVMEDIA_TYPE_VIDEO) { + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(link->format); fprintf(outfile, " [ label= \"fmt:%s w:%d h:%d tb:%d/%d\" ]", - av_pix_fmt_descriptors[link->format].name, - link->w, link->h, link->time_base.num, + desc->name, link->w, link->h, link->time_base.num, link->time_base.den); } else if (link->type == AVMEDIA_TYPE_AUDIO) { char buf[255];