X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Futils.c;h=f13b271fc62764ea55560aee41ec54af8efc3ace;hb=6ce9b4310cf1eba1a356191f30460a97e6653b91;hp=670803b6a56fec814d104d82bfa4870851ff4ba8;hpb=07f2a575c50a2473633113d4591db00d0dca3128;p=ffmpeg diff --git a/libavcodec/utils.c b/libavcodec/utils.c index 670803b6a56..f13b271fc62 100644 --- a/libavcodec/utils.c +++ b/libavcodec/utils.c @@ -21,16 +21,15 @@ */ /** - * @file libavcodec/utils.c + * @file * utils. */ -/* needed for mkstemp() */ -#define _XOPEN_SOURCE 600 - #include "libavutil/avstring.h" #include "libavutil/integer.h" #include "libavutil/crc.h" +#include "libavutil/pixdesc.h" +#include "libavcore/imgutils.h" #include "avcodec.h" #include "dsputil.h" #include "opt.h" @@ -41,9 +40,6 @@ #include #include #include -#if !HAVE_MKSTEMP -#include -#endif static int volatile entangled_thread_counter=0; int (*ff_lockmgr_cb)(void **mutex, enum AVLockOp op); @@ -99,6 +95,11 @@ void register_avcodec(AVCodec *codec) } #endif +unsigned avcodec_get_edge_width(void) +{ + return EDGE_WIDTH; +} + void avcodec_set_dimensions(AVCodecContext *s, int width, int height){ s->coded_width = width; s->coded_height= height; @@ -117,7 +118,7 @@ typedef struct InternalBuffer{ #define INTERNAL_BUFFER_SIZE 32 -void avcodec_align_dimensions(AVCodecContext *s, int *width, int *height){ +void avcodec_align_dimensions2(AVCodecContext *s, int *width, int *height, int linesize_align[4]){ int w_align= 1; int h_align= 1; @@ -180,15 +181,43 @@ void avcodec_align_dimensions(AVCodecContext *s, int *width, int *height){ *height= FFALIGN(*height, h_align); if(s->codec_id == CODEC_ID_H264) *height+=2; // some of the optimized chroma MC reads one line too much + + linesize_align[0] = + linesize_align[1] = + linesize_align[2] = + linesize_align[3] = STRIDE_ALIGN; +//STRIDE_ALIGN is 8 for SSE* but this does not work for SVQ1 chroma planes +//we could change STRIDE_ALIGN to 16 for x86/sse but it would increase the +//picture size unneccessarily in some cases. The solution here is not +//pretty and better ideas are welcome! +#if HAVE_MMX + if(s->codec_id == CODEC_ID_SVQ1 || s->codec_id == CODEC_ID_VP5 || + s->codec_id == CODEC_ID_VP6 || s->codec_id == CODEC_ID_VP6F || + s->codec_id == CODEC_ID_VP6A) { + linesize_align[0] = + linesize_align[1] = + linesize_align[2] = 16; + } +#endif } -int avcodec_check_dimensions(void *av_log_ctx, unsigned int w, unsigned int h){ - if((int)w>0 && (int)h>0 && (w+128)*(uint64_t)(h+128) < INT_MAX/8) - return 0; +void avcodec_align_dimensions(AVCodecContext *s, int *width, int *height){ + int chroma_shift = av_pix_fmt_descriptors[s->pix_fmt].log2_chroma_w; + int linesize_align[4]; + int align; + avcodec_align_dimensions2(s, width, height, linesize_align); + align = FFMAX(linesize_align[0], linesize_align[3]); + linesize_align[1] <<= chroma_shift; + linesize_align[2] <<= chroma_shift; + align = FFMAX3(align, linesize_align[1], linesize_align[2]); + *width=FFALIGN(*width, align); +} - av_log(av_log_ctx, AV_LOG_ERROR, "picture size invalid (%ux%u)\n", w, h); - return -1; +#if LIBAVCODEC_VERSION_MAJOR < 53 +int avcodec_check_dimensions(void *av_log_ctx, unsigned int w, unsigned int h){ + return av_check_image_size(w, h, 0, av_log_ctx); } +#endif int avcodec_default_get_buffer(AVCodecContext *s, AVFrame *pic){ int i; @@ -206,7 +235,7 @@ int avcodec_default_get_buffer(AVCodecContext *s, AVFrame *pic){ return -1; } - if(avcodec_check_dimensions(s,w,h)) + if(av_check_image_size(w, h, 0, s)) return -1; if(s->internal_buffer==NULL){ @@ -244,7 +273,7 @@ int avcodec_default_get_buffer(AVCodecContext *s, AVFrame *pic){ avcodec_get_chroma_sub_sample(s->pix_fmt, &h_chroma_shift, &v_chroma_shift); - avcodec_align_dimensions(s, &w, &h); + avcodec_align_dimensions2(s, &w, &h, stride_align); if(!(s->flags&CODEC_FLAG_EMU_EDGE)){ w+= EDGE_WIDTH*2; @@ -254,27 +283,17 @@ int avcodec_default_get_buffer(AVCodecContext *s, AVFrame *pic){ do { // NOTE: do not align linesizes individually, this breaks e.g. assumptions // that linesize[0] == 2*linesize[1] in the MPEG-encoder for 4:2:2 - ff_fill_linesize(&picture, s->pix_fmt, w); + av_fill_image_linesizes(picture.linesize, s->pix_fmt, w); // increase alignment of w for next try (rhs gives the lowest bit set in w) w += w & ~(w-1); unaligned = 0; for (i=0; i<4; i++){ -//STRIDE_ALIGN is 8 for SSE* but this does not work for SVQ1 chroma planes -//we could change STRIDE_ALIGN to 16 for x86/sse but it would increase the -//picture size unneccessarily in some cases. The solution here is not -//pretty and better ideas are welcome! -#if HAVE_MMX - if(s->codec_id == CODEC_ID_SVQ1) - stride_align[i]= 16; - else -#endif - stride_align[i] = STRIDE_ALIGN; unaligned |= picture.linesize[i] % stride_align[i]; } } while (unaligned); - tmpsize = ff_fill_pointer(&picture, NULL, s->pix_fmt, h); + tmpsize = av_fill_image_pointers(picture.data, s->pix_fmt, h, NULL, picture.linesize); if (tmpsize < 0) return -1; @@ -296,7 +315,7 @@ int avcodec_default_get_buffer(AVCodecContext *s, AVFrame *pic){ if(buf->base[i]==NULL) return -1; memset(buf->base[i], 128, size[i]); - // no edge if EDEG EMU or not planar YUV + // no edge if EDGE EMU or not planar YUV if((s->flags&CODEC_FLAG_EMU_EDGE) || !size[2]) buf->data[i] = buf->base[i]; else @@ -468,14 +487,14 @@ int attribute_align_arg avcodec_open(AVCodecContext *avctx, AVCodec *codec) #define SANE_NB_CHANNELS 128U if (((avctx->coded_width || avctx->coded_height) - && avcodec_check_dimensions(avctx, avctx->coded_width, avctx->coded_height)) + && av_check_image_size(avctx->coded_width, avctx->coded_height, 0, avctx)) || avctx->channels > SANE_NB_CHANNELS) { ret = AVERROR(EINVAL); goto free_and_end; } avctx->codec = codec; - if ((avctx->codec_type == CODEC_TYPE_UNKNOWN || avctx->codec_type == codec->type) && + if ((avctx->codec_type == AVMEDIA_TYPE_UNKNOWN || avctx->codec_type == codec->type) && avctx->codec_id == CODEC_ID_NONE) { avctx->codec_type = codec->type; avctx->codec_id = codec->id; @@ -486,6 +505,13 @@ int attribute_align_arg avcodec_open(AVCodecContext *avctx, AVCodec *codec) } avctx->frame_number = 0; if(avctx->codec->init){ + if(avctx->codec_type == AVMEDIA_TYPE_VIDEO && + avctx->codec->max_lowres < avctx->lowres){ + av_log(avctx, AV_LOG_ERROR, "The maximum value for lowres supported by the decoder is %d\n", + avctx->codec->max_lowres); + goto free_and_end; + } + ret = avctx->codec->init(avctx); if (ret < 0) { goto free_and_end; @@ -528,7 +554,7 @@ int attribute_align_arg avcodec_encode_video(AVCodecContext *avctx, uint8_t *buf av_log(avctx, AV_LOG_ERROR, "buffer smaller than minimum size\n"); return -1; } - if(avcodec_check_dimensions(avctx,avctx->width,avctx->height)) + if(av_check_image_size(avctx->width, avctx->height, 0, avctx)) return -1; if((avctx->codec->capabilities & CODEC_CAP_DELAY) || pict){ int ret = avctx->codec->encode(avctx, buf, buf_size, pict); @@ -578,7 +604,7 @@ int attribute_align_arg avcodec_decode_video2(AVCodecContext *avctx, AVFrame *pi int ret; *got_picture_ptr= 0; - if((avctx->coded_width||avctx->coded_height) && avcodec_check_dimensions(avctx,avctx->coded_width,avctx->coded_height)) + if((avctx->coded_width||avctx->coded_height) && av_check_image_size(avctx->coded_width, avctx->coded_height, 0, avctx)) return -1; if((avctx->codec->capabilities & CODEC_CAP_DELAY) || avpkt->size){ ret = avctx->codec->decode(avctx, picture, got_picture_ptr, @@ -662,7 +688,27 @@ int avcodec_decode_subtitle2(AVCodecContext *avctx, AVSubtitle *sub, return ret; } -int avcodec_close(AVCodecContext *avctx) +void avsubtitle_free(AVSubtitle *sub) +{ + int i; + + for (i = 0; i < sub->num_rects; i++) + { + av_freep(&sub->rects[i]->pict.data[0]); + av_freep(&sub->rects[i]->pict.data[1]); + av_freep(&sub->rects[i]->pict.data[2]); + av_freep(&sub->rects[i]->pict.data[3]); + av_freep(&sub->rects[i]->text); + av_freep(&sub->rects[i]->ass); + av_freep(&sub->rects[i]); + } + + av_freep(&sub->rects); + + memset(sub, 0, sizeof(AVSubtitle)); +} + +av_cold int avcodec_close(AVCodecContext *avctx) { /* If there is a user-supplied mutex locking routine, call it. */ if (ff_lockmgr_cb) { @@ -682,7 +728,10 @@ int avcodec_close(AVCodecContext *avctx) if (avctx->codec && avctx->codec->close) avctx->codec->close(avctx); avcodec_default_free_buffers(avctx); + avctx->coded_frame = NULL; av_freep(&avctx->priv_data); + if(avctx->codec && avctx->codec->encode) + av_freep(&avctx->extradata); avctx->codec = NULL; entangled_thread_counter--; @@ -695,14 +744,18 @@ int avcodec_close(AVCodecContext *avctx) AVCodec *avcodec_find_encoder(enum CodecID id) { - AVCodec *p; + AVCodec *p, *experimental=NULL; p = first_avcodec; while (p) { - if (p->encode != NULL && p->id == id) - return p; + if (p->encode != NULL && p->id == id) { + if (p->capabilities & CODEC_CAP_EXPERIMENTAL && !experimental) { + experimental = p; + } else + return p; + } p = p->next; } - return NULL; + return experimental; } AVCodec *avcodec_find_encoder_by_name(const char *name) @@ -745,28 +798,22 @@ AVCodec *avcodec_find_decoder_by_name(const char *name) return NULL; } -int av_get_bit_rate(AVCodecContext *ctx) +static int get_bit_rate(AVCodecContext *ctx) { int bit_rate; int bits_per_sample; switch(ctx->codec_type) { - case CODEC_TYPE_VIDEO: + case AVMEDIA_TYPE_VIDEO: + case AVMEDIA_TYPE_DATA: + case AVMEDIA_TYPE_SUBTITLE: + case AVMEDIA_TYPE_ATTACHMENT: bit_rate = ctx->bit_rate; break; - case CODEC_TYPE_AUDIO: + case AVMEDIA_TYPE_AUDIO: bits_per_sample = av_get_bits_per_sample(ctx->codec_id); bit_rate = bits_per_sample ? ctx->sample_rate * ctx->channels * bits_per_sample : ctx->bit_rate; break; - case CODEC_TYPE_DATA: - bit_rate = ctx->bit_rate; - break; - case CODEC_TYPE_SUBTITLE: - bit_rate = ctx->bit_rate; - break; - case CODEC_TYPE_ATTACHMENT: - bit_rate = ctx->bit_rate; - break; default: bit_rate = 0; break; @@ -774,6 +821,21 @@ int av_get_bit_rate(AVCodecContext *ctx) return bit_rate; } +size_t av_get_codec_tag_string(char *buf, size_t buf_size, unsigned int codec_tag) +{ + int i, len, ret = 0; + + for (i = 0; i < 4; i++) { + len = snprintf(buf, buf_size, + isprint(codec_tag&0xFF) ? "%c" : "[%d]", codec_tag&0xFF); + buf += len; + buf_size = buf_size > len ? buf_size - len : 0; + ret += len; + codec_tag>>=8; + } + return ret; +} + void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode) { const char *codec_name; @@ -797,22 +859,14 @@ void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode) codec_name = enc->codec_name; } else { /* output avi tags */ - if( isprint(enc->codec_tag&0xFF) && isprint((enc->codec_tag>>8)&0xFF) - && isprint((enc->codec_tag>>16)&0xFF) && isprint((enc->codec_tag>>24)&0xFF)){ - snprintf(buf1, sizeof(buf1), "%c%c%c%c / 0x%04X", - enc->codec_tag & 0xff, - (enc->codec_tag >> 8) & 0xff, - (enc->codec_tag >> 16) & 0xff, - (enc->codec_tag >> 24) & 0xff, - enc->codec_tag); - } else { - snprintf(buf1, sizeof(buf1), "0x%04x", enc->codec_tag); - } + char tag_buf[32]; + av_get_codec_tag_string(tag_buf, sizeof(tag_buf), enc->codec_tag); + snprintf(buf1, sizeof(buf1), "%s / 0x%04X", tag_buf, enc->codec_tag); codec_name = buf1; } switch(enc->codec_type) { - case CODEC_TYPE_VIDEO: + case AVMEDIA_TYPE_VIDEO: snprintf(buf, buf_size, "Video: %s%s", codec_name, enc->mb_decision ? " (hq)" : ""); @@ -847,7 +901,7 @@ void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode) ", q=%d-%d", enc->qmin, enc->qmax); } break; - case CODEC_TYPE_AUDIO: + case AVMEDIA_TYPE_AUDIO: snprintf(buf, buf_size, "Audio: %s", codec_name); @@ -862,13 +916,13 @@ void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode) ", %s", avcodec_get_sample_fmt_name(enc->sample_fmt)); } break; - case CODEC_TYPE_DATA: + case AVMEDIA_TYPE_DATA: snprintf(buf, buf_size, "Data: %s", codec_name); break; - case CODEC_TYPE_SUBTITLE: + case AVMEDIA_TYPE_SUBTITLE: snprintf(buf, buf_size, "Subtitle: %s", codec_name); break; - case CODEC_TYPE_ATTACHMENT: + case AVMEDIA_TYPE_ATTACHMENT: snprintf(buf, buf_size, "Attachment: %s", codec_name); break; default: @@ -883,7 +937,7 @@ void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode) snprintf(buf + strlen(buf), buf_size - strlen(buf), ", pass 2"); } - bitrate = av_get_bit_rate(enc); + bitrate = get_bit_rate(enc); if (bitrate != 0) { snprintf(buf + strlen(buf), buf_size - strlen(buf), ", %d kb/s", bitrate / 1000); @@ -1037,167 +1091,24 @@ unsigned int av_xiphlacing(unsigned char *s, unsigned int v) return n; } -/* Wrapper to work around the lack of mkstemp() on mingw/cygin. - * Also, tries to create file in /tmp first, if possible. - * *prefix can be a character constant; *filename will be allocated internally. - * Returns file descriptor of opened file (or -1 on error) - * and opened file name in **filename. */ -int av_tempfile(char *prefix, char **filename) { - int fd=-1; -#if !HAVE_MKSTEMP - *filename = tempnam(".", prefix); -#else - size_t len = strlen(prefix) + 12; /* room for "/tmp/" and "XXXXXX\0" */ - *filename = av_malloc(len); -#endif - /* -----common section-----*/ - if (*filename == NULL) { - av_log(NULL, AV_LOG_ERROR, "ff_tempfile: Cannot allocate file name\n"); - return -1; - } -#if !HAVE_MKSTEMP - fd = open(*filename, O_RDWR | O_BINARY | O_CREAT, 0444); -#else - snprintf(*filename, len, "/tmp/%sXXXXXX", prefix); - fd = mkstemp(*filename); - if (fd < 0) { - snprintf(*filename, len, "./%sXXXXXX", prefix); - fd = mkstemp(*filename); - } -#endif - /* -----common section-----*/ - if (fd < 0) { - av_log(NULL, AV_LOG_ERROR, "ff_tempfile: Cannot open temporary file %s\n", *filename); - return -1; - } - return fd; /* success */ -} - -typedef struct { - const char *abbr; - int width, height; -} VideoFrameSizeAbbr; - -typedef struct { - const char *abbr; - int rate_num, rate_den; -} VideoFrameRateAbbr; - -static const VideoFrameSizeAbbr video_frame_size_abbrs[] = { - { "ntsc", 720, 480 }, - { "pal", 720, 576 }, - { "qntsc", 352, 240 }, /* VCD compliant NTSC */ - { "qpal", 352, 288 }, /* VCD compliant PAL */ - { "sntsc", 640, 480 }, /* square pixel NTSC */ - { "spal", 768, 576 }, /* square pixel PAL */ - { "film", 352, 240 }, - { "ntsc-film", 352, 240 }, - { "sqcif", 128, 96 }, - { "qcif", 176, 144 }, - { "cif", 352, 288 }, - { "4cif", 704, 576 }, - { "16cif", 1408,1152 }, - { "qqvga", 160, 120 }, - { "qvga", 320, 240 }, - { "vga", 640, 480 }, - { "svga", 800, 600 }, - { "xga", 1024, 768 }, - { "uxga", 1600,1200 }, - { "qxga", 2048,1536 }, - { "sxga", 1280,1024 }, - { "qsxga", 2560,2048 }, - { "hsxga", 5120,4096 }, - { "wvga", 852, 480 }, - { "wxga", 1366, 768 }, - { "wsxga", 1600,1024 }, - { "wuxga", 1920,1200 }, - { "woxga", 2560,1600 }, - { "wqsxga", 3200,2048 }, - { "wquxga", 3840,2400 }, - { "whsxga", 6400,4096 }, - { "whuxga", 7680,4800 }, - { "cga", 320, 200 }, - { "ega", 640, 350 }, - { "hd480", 852, 480 }, - { "hd720", 1280, 720 }, - { "hd1080", 1920,1080 }, -}; - -static const VideoFrameRateAbbr video_frame_rate_abbrs[]= { - { "ntsc", 30000, 1001 }, - { "pal", 25, 1 }, - { "qntsc", 30000, 1001 }, /* VCD compliant NTSC */ - { "qpal", 25, 1 }, /* VCD compliant PAL */ - { "sntsc", 30000, 1001 }, /* square pixel NTSC */ - { "spal", 25, 1 }, /* square pixel PAL */ - { "film", 24, 1 }, - { "ntsc-film", 24000, 1001 }, -}; +#if LIBAVCODEC_VERSION_MAJOR < 53 +#include "libavcore/parseutils.h" int av_parse_video_frame_size(int *width_ptr, int *height_ptr, const char *str) { - int i; - int n = FF_ARRAY_ELEMS(video_frame_size_abbrs); - char *p; - int frame_width = 0, frame_height = 0; - - for(i=0;inum = video_frame_rate_abbrs[i].rate_num; - frame_rate->den = video_frame_rate_abbrs[i].rate_den; - return 0; - } - - /* Then, we try to parse it as fraction */ - cp = strchr(arg, '/'); - if (!cp) - cp = strchr(arg, ':'); - if (cp) { - char* cpp; - frame_rate->num = strtol(arg, &cpp, 10); - if (cpp != arg || cpp == cp) - frame_rate->den = strtol(cp+1, &cpp, 10); - else - frame_rate->num = 0; - } - else { - /* Finally we give up and parse it as double */ - AVRational time_base = av_d2q(strtod(arg, 0), 1001000); - frame_rate->den = time_base.den; - frame_rate->num = time_base.num; - } - if (!frame_rate->num || !frame_rate->den) - return -1; - else - return 0; + for(i=0; i>8 )&0xFF)<<8 ) + + (toupper((x>>16)&0xFF)<<16) + + (toupper((x>>24)&0xFF)<<24); +}