X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Futils.c;h=9ca8a2d38ea10dc9c54faffa74f8e4a3e62051b3;hb=a861e7e3b6c26910dce5d152fa7c35043678e610;hp=74192caf21d68dab06a51c7227beb12c60508ffb;hpb=08cb1950209b53bf98bf2014ca584a6b0e138917;p=ffmpeg diff --git a/libavcodec/utils.c b/libavcodec/utils.c index 74192caf21d..9ca8a2d38ea 100644 --- a/libavcodec/utils.c +++ b/libavcodec/utils.c @@ -34,7 +34,7 @@ #include #include #include -#ifdef __MINGW32__ +#if !defined(HAVE_MKSTEMP) #include #endif @@ -147,6 +147,8 @@ typedef struct InternalBuffer{ uint8_t *base[4]; uint8_t *data[4]; int linesize[4]; + int width, height; + enum PixelFormat pix_fmt; }InternalBuffer; #define INTERNAL_BUFFER_SIZE 32 @@ -251,6 +253,13 @@ int avcodec_default_get_buffer(AVCodecContext *s, AVFrame *pic){ picture_number= &(((InternalBuffer*)s->internal_buffer)[INTERNAL_BUFFER_SIZE-1]).last_pic_num; //FIXME ugly hack (*picture_number)++; + if(buf->base[0] && (buf->width != w || buf->height != h || buf->pix_fmt != s->pix_fmt)){ + for(i=0; i<4; i++){ + av_freep(&buf->base[i]); + buf->data[i]= NULL; + } + } + if(buf->base[0]){ pic->age= *picture_number - buf->last_pic_num; buf->last_pic_num= *picture_number; @@ -267,11 +276,13 @@ int avcodec_default_get_buffer(AVCodecContext *s, AVFrame *pic){ w+= EDGE_WIDTH*2; h+= EDGE_WIDTH*2; } + avcodec_align_dimensions(s, &w, &h); + avpicture_fill(&picture, NULL, s->pix_fmt, w, h); pixel_size= picture.linesize[0]*8 / w; //av_log(NULL, AV_LOG_ERROR, "%d %d %d %d\n", (int)picture.data[1], w, h, s->pix_fmt); assert(pixel_size>=1); - //FIXME next ensures that linesize= 2^x uvlinesize, thats needed because some MC code assumes it + //FIXME next ensures that linesize= 2^x uvlinesize, that is needed because some MC code assumes it if(pixel_size == 3*8) w= ALIGN(w, STRIDE_ALIGN<data[i] = buf->base[i] + ALIGN((buf->linesize[i]*EDGE_WIDTH>>v_shift) + (EDGE_WIDTH>>h_shift), STRIDE_ALIGN); } + buf->width = s->width; + buf->height = s->height; + buf->pix_fmt= s->pix_fmt; pic->age= 256*256*256*64; } pic->type= FF_BUFFER_TYPE_INTERNAL; @@ -400,7 +414,7 @@ static const char* context_to_name(void* ptr) { } #define OFFSET(x) offsetof(AVCodecContext,x) -#define DEFAULT 0 //should be NAN but it doesnt work as its not a constant in glibc as required by ANSI/ISO C +#define DEFAULT 0 //should be NAN but it does not work as it is not a constant in glibc as required by ANSI/ISO C //these names are too long to be readable #define V AV_OPT_FLAG_VIDEO_PARAM #define A AV_OPT_FLAG_AUDIO_PARAM @@ -453,6 +467,18 @@ static const AVOption options[]={ {"local_header", "place global headers at every keyframe instead of in extradata", 0, FF_OPT_TYPE_CONST, CODEC_FLAG2_LOCAL_HEADER, INT_MIN, INT_MAX, V|E, "flags2"}, {"sub_id", NULL, OFFSET(sub_id), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, {"me_method", "set motion estimation method", OFFSET(me_method), FF_OPT_TYPE_INT, ME_EPZS, INT_MIN, INT_MAX, V|E, "me_method"}, +#if LIBAVCODEC_VERSION_INT < ((52<<16)+(0<<8)+0) +{"me", "set motion estimation method (deprecated, use me_method instead)", OFFSET(me_method), FF_OPT_TYPE_INT, ME_EPZS, INT_MIN, INT_MAX, V|E, "me_method"}, +#endif +{"zero", "zero motion estimation (fastest)", 0, FF_OPT_TYPE_CONST, ME_ZERO, INT_MIN, INT_MAX, V|E, "me_method" }, +{"full", "full motion estimation (slowest)", 0, FF_OPT_TYPE_CONST, ME_FULL, INT_MIN, INT_MAX, V|E, "me_method" }, +{"epzs", "EPZS motion estimation (default)", 0, FF_OPT_TYPE_CONST, ME_EPZS, INT_MIN, INT_MAX, V|E, "me_method" }, +{"log", "log motion estimation", 0, FF_OPT_TYPE_CONST, ME_LOG, INT_MIN, INT_MAX, V|E, "me_method" }, +{"phods", "phods motion estimation", 0, FF_OPT_TYPE_CONST, ME_PHODS, INT_MIN, INT_MAX, V|E, "me_method" }, +{"x1", "X1 motion estimation", 0, FF_OPT_TYPE_CONST, ME_X1, INT_MIN, INT_MAX, V|E, "me_method" }, +{"hex", "hex motion estimation", 0, FF_OPT_TYPE_CONST, ME_HEX, INT_MIN, INT_MAX, V|E, "me_method" }, +{"umh", "umh motion estimation", 0, FF_OPT_TYPE_CONST, ME_UMH, INT_MIN, INT_MAX, V|E, "me_method" }, +{"iter", "iter motion estimation", 0, FF_OPT_TYPE_CONST, ME_ITER, INT_MIN, INT_MAX, V|E, "me_method" }, {"extradata_size", NULL, OFFSET(extradata_size), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, {"time_base", NULL, OFFSET(time_base), FF_OPT_TYPE_RATIONAL, DEFAULT, INT_MIN, INT_MAX}, {"g", "set the group of picture size", OFFSET(gop_size), FF_OPT_TYPE_INT, 12, INT_MIN, INT_MAX, V|E}, @@ -511,7 +537,7 @@ static const AVOption options[]={ {"strict", "strictly conform to all the things in the spec no matter what consequences", 0, FF_OPT_TYPE_CONST, FF_COMPLIANCE_STRICT, INT_MIN, INT_MAX, V|E, "strict"}, {"normal", NULL, 0, FF_OPT_TYPE_CONST, FF_COMPLIANCE_NORMAL, INT_MIN, INT_MAX, V|E, "strict"}, {"inofficial", "allow inofficial extensions", 0, FF_OPT_TYPE_CONST, FF_COMPLIANCE_INOFFICIAL, INT_MIN, INT_MAX, V|E, "strict"}, -{"experimental", "allow non standarized experimental things", 0, FF_OPT_TYPE_CONST, FF_COMPLIANCE_EXPERIMENTAL, INT_MIN, INT_MAX, V|E, "strict"}, +{"experimental", "allow non standardized experimental things", 0, FF_OPT_TYPE_CONST, FF_COMPLIANCE_EXPERIMENTAL, INT_MIN, INT_MAX, V|E, "strict"}, {"b_qoffset", "qp offset between p and b frames", OFFSET(b_quant_offset), FF_OPT_TYPE_FLOAT, 1.25, FLT_MIN, FLT_MAX, V|E}, {"er", "set error resilience strategy", OFFSET(error_resilience), FF_OPT_TYPE_INT, FF_ER_CAREFUL, INT_MIN, INT_MAX, A|V|D, "er"}, {"careful", NULL, 0, FF_OPT_TYPE_CONST, FF_ER_CAREFUL, INT_MIN, INT_MAX, V|D, "er"}, @@ -636,6 +662,9 @@ static const AVOption options[]={ {"coder", NULL, OFFSET(coder_type), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E, "coder"}, {"vlc", "variable length coder / huffman coder", 0, FF_OPT_TYPE_CONST, FF_CODER_TYPE_VLC, INT_MIN, INT_MAX, V|E, "coder"}, {"ac", "arithmetic coder", 0, FF_OPT_TYPE_CONST, FF_CODER_TYPE_AC, INT_MIN, INT_MAX, V|E, "coder"}, +{"raw", "raw (no encoding)", 0, FF_OPT_TYPE_CONST, FF_CODER_TYPE_RAW, INT_MIN, INT_MAX, V|E, "coder"}, +{"rle", "run-length coder", 0, FF_OPT_TYPE_CONST, FF_CODER_TYPE_RLE, INT_MIN, INT_MAX, V|E, "coder"}, +{"deflate", "deflate-based coder", 0, FF_OPT_TYPE_CONST, FF_CODER_TYPE_DEFLATE, INT_MIN, INT_MAX, V|E, "coder"}, {"context", "context model", OFFSET(context_model), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E}, {"slice_flags", NULL, OFFSET(slice_flags), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, {"xvmc_acceleration", NULL, OFFSET(xvmc_acceleration), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, @@ -667,6 +696,10 @@ static const AVOption options[]={ {"skip_bottom", "number of macroblock rows at the bottom which are skipped", OFFSET(skip_bottom), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|D}, {"profile", NULL, OFFSET(profile), FF_OPT_TYPE_INT, FF_PROFILE_UNKNOWN, INT_MIN, INT_MAX, V|A|E, "profile"}, {"unknown", NULL, 0, FF_OPT_TYPE_CONST, FF_PROFILE_UNKNOWN, INT_MIN, INT_MAX, V|A|E, "profile"}, +{"aac_main", NULL, 0, FF_OPT_TYPE_CONST, FF_PROFILE_AAC_MAIN, INT_MIN, INT_MAX, A|E, "profile"}, +{"aac_low", NULL, 0, FF_OPT_TYPE_CONST, FF_PROFILE_AAC_LOW, INT_MIN, INT_MAX, A|E, "profile"}, +{"aac_ssr", NULL, 0, FF_OPT_TYPE_CONST, FF_PROFILE_AAC_SSR, INT_MIN, INT_MAX, A|E, "profile"}, +{"aac_ltp", NULL, 0, FF_OPT_TYPE_CONST, FF_PROFILE_AAC_LTP, INT_MIN, INT_MAX, A|E, "profile"}, {"level", NULL, OFFSET(level), FF_OPT_TYPE_INT, FF_LEVEL_UNKNOWN, INT_MIN, INT_MAX, V|A|E, "level"}, {"unknown", NULL, 0, FF_OPT_TYPE_CONST, FF_LEVEL_UNKNOWN, INT_MIN, INT_MAX, V|A|E, "level"}, {"lowres", "decode at 1= 1/2, 2=1/4, 3=1/8 resolutions", OFFSET(lowres), FF_OPT_TYPE_INT, 0, 0, INT_MAX, V|D}, @@ -691,11 +724,11 @@ static const AVOption options[]={ {"bpyramid", "allows B-frames to be used as references for predicting", 0, FF_OPT_TYPE_CONST, CODEC_FLAG2_BPYRAMID, INT_MIN, INT_MAX, V|E, "flags2"}, {"wpred", "weighted biprediction for b-frames (H.264)", 0, FF_OPT_TYPE_CONST, CODEC_FLAG2_WPRED, INT_MIN, INT_MAX, V|E, "flags2"}, {"mixed_refs", "one reference per partition, as opposed to one reference per macroblock", 0, FF_OPT_TYPE_CONST, CODEC_FLAG2_MIXED_REFS, INT_MIN, INT_MAX, V|E, "flags2"}, -{"8x8dct", "high profile 8x8 transform (H.264)", 0, FF_OPT_TYPE_CONST, CODEC_FLAG2_8X8DCT, INT_MIN, INT_MAX, V|E, "flags2"}, +{"dct8x8", "high profile 8x8 transform (H.264)", 0, FF_OPT_TYPE_CONST, CODEC_FLAG2_8X8DCT, INT_MIN, INT_MAX, V|E, "flags2"}, {"fastpskip", "fast pskip (H.264)", 0, FF_OPT_TYPE_CONST, CODEC_FLAG2_FASTPSKIP, INT_MIN, INT_MAX, V|E, "flags2"}, {"aud", "access unit delimiters (H.264)", 0, FF_OPT_TYPE_CONST, CODEC_FLAG2_AUD, INT_MIN, INT_MAX, V|E, "flags2"}, {"brdo", "b-frame rate-distortion optimization", 0, FF_OPT_TYPE_CONST, CODEC_FLAG2_BRDO, INT_MIN, INT_MAX, V|E, "flags2"}, -{"skiprd", "RD optimal MB level residual skiping", 0, FF_OPT_TYPE_CONST, CODEC_FLAG2_SKIP_RD, INT_MIN, INT_MAX, V|E, "flags2"}, +{"skiprd", "RD optimal MB level residual skipping", 0, FF_OPT_TYPE_CONST, CODEC_FLAG2_SKIP_RD, INT_MIN, INT_MAX, V|E, "flags2"}, {"complexityblur", "reduce fluctuations in qp (before curve compression)", OFFSET(complexityblur), FF_OPT_TYPE_FLOAT, 20.0, FLT_MIN, FLT_MAX, V|E}, {"deblockalpha", "in-loop deblocking filter alphac0 parameter", OFFSET(deblockalpha), FF_OPT_TYPE_INT, DEFAULT, -6, 6, V|E}, {"deblockbeta", "in-loop deblocking filter beta parameter", OFFSET(deblockbeta), FF_OPT_TYPE_INT, DEFAULT, -6, 6, V|E}, @@ -720,6 +753,7 @@ static const AVOption options[]={ {"timecode_frame_start", "GOP timecode frame start number, in non drop frame format", OFFSET(timecode_frame_start), FF_OPT_TYPE_INT, 0, 0, INT_MAX, V|E}, {"drop_frame_timecode", NULL, 0, FF_OPT_TYPE_CONST, CODEC_FLAG2_DROP_FRAME_TIMECODE, INT_MIN, INT_MAX, V|E, "flags2"}, {"non_linear_q", "use non linear quantizer", 0, FF_OPT_TYPE_CONST, CODEC_FLAG2_NON_LINEAR_QUANT, INT_MIN, INT_MAX, V|E, "flags2"}, +{"request_channels", "set desired number of audio channels", OFFSET(request_channels), FF_OPT_TYPE_INT, DEFAULT, 0, INT_MAX, A|D}, {NULL}, }; @@ -738,6 +772,7 @@ void avcodec_get_context_defaults2(AVCodecContext *s, enum CodecType codec_type) s->av_class= &av_codec_context_class; + s->codec_type = codec_type; if(codec_type == CODEC_TYPE_AUDIO) flags= AV_OPT_FLAG_AUDIO_PARAM; else if(codec_type == CODEC_TYPE_VIDEO) @@ -795,7 +830,7 @@ AVFrame *avcodec_alloc_frame(void){ return pic; } -int avcodec_open(AVCodecContext *avctx, AVCodec *codec) +int attribute_align_arg avcodec_open(AVCodecContext *avctx, AVCodec *codec) { int ret= -1; @@ -810,8 +845,10 @@ int avcodec_open(AVCodecContext *avctx, AVCodec *codec) if (codec->priv_data_size > 0) { avctx->priv_data = av_mallocz(codec->priv_data_size); - if (!avctx->priv_data) + if (!avctx->priv_data) { + ret = AVERROR(ENOMEM); goto end; + } } else { avctx->priv_data = NULL; } @@ -823,17 +860,20 @@ int avcodec_open(AVCodecContext *avctx, AVCodec *codec) if((avctx->coded_width||avctx->coded_height) && avcodec_check_dimensions(avctx,avctx->coded_width,avctx->coded_height)){ av_freep(&avctx->priv_data); + ret = AVERROR(EINVAL); goto end; } avctx->codec = codec; avctx->codec_id = codec->id; avctx->frame_number = 0; - ret = avctx->codec->init(avctx); - if (ret < 0) { - av_freep(&avctx->priv_data); - avctx->codec= NULL; - goto end; + if(avctx->codec->init){ + ret = avctx->codec->init(avctx); + if (ret < 0) { + av_freep(&avctx->priv_data); + avctx->codec= NULL; + goto end; + } } ret=0; end: @@ -841,7 +881,7 @@ end: return ret; } -int avcodec_encode_audio(AVCodecContext *avctx, uint8_t *buf, int buf_size, +int attribute_align_arg avcodec_encode_audio(AVCodecContext *avctx, uint8_t *buf, int buf_size, const short *samples) { if(buf_size < FF_MIN_BUFFER_SIZE && 0){ @@ -856,7 +896,7 @@ int avcodec_encode_audio(AVCodecContext *avctx, uint8_t *buf, int buf_size, return 0; } -int avcodec_encode_video(AVCodecContext *avctx, uint8_t *buf, int buf_size, +int attribute_align_arg avcodec_encode_video(AVCodecContext *avctx, uint8_t *buf, int buf_size, const AVFrame *pict) { if(buf_size < FF_MIN_BUFFER_SIZE){ @@ -884,7 +924,7 @@ int avcodec_encode_subtitle(AVCodecContext *avctx, uint8_t *buf, int buf_size, return ret; } -int avcodec_decode_video(AVCodecContext *avctx, AVFrame *picture, +int attribute_align_arg avcodec_decode_video(AVCodecContext *avctx, AVFrame *picture, int *got_picture_ptr, uint8_t *buf, int buf_size) { @@ -907,7 +947,7 @@ int avcodec_decode_video(AVCodecContext *avctx, AVFrame *picture, return ret; } -int avcodec_decode_audio2(AVCodecContext *avctx, int16_t *samples, +int attribute_align_arg avcodec_decode_audio2(AVCodecContext *avctx, int16_t *samples, int *frame_size_ptr, uint8_t *buf, int buf_size) { @@ -968,6 +1008,8 @@ int avcodec_close(AVCodecContext *avctx) return -1; } + if (ENABLE_THREADS && avctx->thread_opaque) + avcodec_thread_free(avctx); if (avctx->codec->close) avctx->codec->close(avctx); avcodec_default_free_buffers(avctx); @@ -1194,9 +1236,9 @@ static void init_crcs(void){ av_crc8005 = av_mallocz_static(sizeof(AVCRC) * 257); av_crc07 = av_mallocz_static(sizeof(AVCRC) * 257); #endif - av_crc_init(av_crc04C11DB7, 0, 32, 0x04c11db7, sizeof(AVCRC)*257); - av_crc_init(av_crc8005 , 0, 16, 0x8005 , sizeof(AVCRC)*257); - av_crc_init(av_crc07 , 0, 8, 0x07 , sizeof(AVCRC)*257); + av_crc_init(av_crc04C11DB7, 0, 32, AV_CRC_32_IEEE, sizeof(AVCRC)*257); + av_crc_init(av_crc8005 , 0, 16, AV_CRC_16 , sizeof(AVCRC)*257); + av_crc_init(av_crc07 , 0, 8, AV_CRC_8_ATM , sizeof(AVCRC)*257); } void avcodec_init(void) @@ -1281,6 +1323,22 @@ int av_get_bits_per_sample(enum CodecID codec_id){ } } +int av_get_bits_per_sample_format(enum SampleFormat sample_fmt) { + switch (sample_fmt) { + case SAMPLE_FMT_U8: + return 8; + case SAMPLE_FMT_S16: + return 16; + case SAMPLE_FMT_S24: + return 24; + case SAMPLE_FMT_S32: + case SAMPLE_FMT_FLT: + return 32; + default: + return 0; + } +} + #if !defined(HAVE_THREADS) int avcodec_thread_init(AVCodecContext *s, int thread_count){ return -1; @@ -1308,7 +1366,7 @@ unsigned int av_xiphlacing(unsigned char *s, unsigned int v) * and opened file name in **filename. */ int av_tempfile(char *prefix, char **filename) { int fd=-1; -#ifdef __MINGW32__ +#if !defined(HAVE_MKSTEMP) *filename = tempnam(".", prefix); #else size_t len = strlen(prefix) + 12; /* room for "/tmp/" and "XXXXXX\0" */ @@ -1319,8 +1377,8 @@ int av_tempfile(char *prefix, char **filename) { av_log(NULL, AV_LOG_ERROR, "ff_tempfile: Cannot allocate file name\n"); return -1; } -#ifdef __MINGW32__ - fd = open(*filename, _O_RDWR | _O_BINARY | _O_CREAT, 0444); +#if !defined(HAVE_MKSTEMP) + fd = open(*filename, O_RDWR | O_BINARY | O_CREAT, 0444); #else snprintf(*filename, len, "/tmp/%sXXXXXX", prefix); fd = mkstemp(*filename); @@ -1336,3 +1394,129 @@ int av_tempfile(char *prefix, char **filename) { } return fd; /* success */ } + +typedef struct { + const char *abbr; + int width, height; +} VideoFrameSizeAbbr; + +typedef struct { + const char *abbr; + int rate_num, rate_den; +} VideoFrameRateAbbr; + +static 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 }, + { "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 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 }, +}; + +int av_parse_video_frame_size(int *width_ptr, int *height_ptr, const char *str) +{ + int i; + int n = sizeof(video_frame_size_abbrs) / sizeof(VideoFrameSizeAbbr); + const 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), DEFAULT_FRAME_RATE_BASE); + frame_rate->den = time_base.den; + frame_rate->num = time_base.num; + } + if (!frame_rate->num || !frame_rate->den) + return -1; + else + return 0; +}