2352 lines · 79.1 KB · C
RawDownload
/* * utils for libavcodec * Copyright (c) 2001 Fabrice Bellard * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at> * * This file is part of FFmpeg. * * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /** * @file * utils. */ #include "config.h"#include "libavutil/attributes.h"#include "libavutil/avassert.h"#include "libavutil/avstring.h"#include "libavutil/bprint.h"#include "libavutil/channel_layout.h"#include "libavutil/crc.h"#include "libavutil/frame.h"#include "libavutil/hwcontext.h"#include "libavutil/internal.h"#include "libavutil/mathematics.h"#include "libavutil/mem_internal.h"#include "libavutil/pixdesc.h"#include "libavutil/imgutils.h"#include "libavutil/samplefmt.h"#include "libavutil/dict.h"#include "libavutil/thread.h"#include "avcodec.h"#include "decode.h"#include "hwconfig.h"#include "libavutil/opt.h"#include "mpegvideo.h"#include "thread.h"#include "frame_thread_encoder.h"#include "internal.h"#include "packet_internal.h"#include "put_bits.h"#include "raw.h"#include "bytestream.h"#include "version.h"#include <stdlib.h>#include <stdarg.h>#include <stdatomic.h>#include <limits.h>#include <float.h>#if CONFIG_ICONV# include <iconv.h>#endif #include "libavutil/ffversion.h"const char av_codec_ffversion[] = "FFmpeg version " FFMPEG_VERSION; static AVMutex codec_mutex = AV_MUTEX_INITIALIZER; void av_fast_padded_malloc(void *ptr, unsigned int *size, size_t min_size){    uint8_t **p = ptr;    if (min_size > SIZE_MAX - AV_INPUT_BUFFER_PADDING_SIZE) {        av_freep(p);        *size = 0;        return;    }    if (!ff_fast_malloc(p, size, min_size + AV_INPUT_BUFFER_PADDING_SIZE, 1))        memset(*p + min_size, 0, AV_INPUT_BUFFER_PADDING_SIZE);} void av_fast_padded_mallocz(void *ptr, unsigned int *size, size_t min_size){    uint8_t **p = ptr;    if (min_size > SIZE_MAX - AV_INPUT_BUFFER_PADDING_SIZE) {        av_freep(p);        *size = 0;        return;    }    if (!ff_fast_malloc(p, size, min_size + AV_INPUT_BUFFER_PADDING_SIZE, 1))        memset(*p, 0, min_size + AV_INPUT_BUFFER_PADDING_SIZE);} int av_codec_is_encoder(const AVCodec *codec){    return codec && (codec->encode_sub || codec->encode2 || codec->receive_packet);} int av_codec_is_decoder(const AVCodec *codec){    return codec && (codec->decode || codec->receive_frame);} int ff_set_dimensions(AVCodecContext *s, int width, int height){    int ret = av_image_check_size2(width, height, s->max_pixels, AV_PIX_FMT_NONE, 0, s);     if (ret < 0)        width = height = 0;     s->coded_width  = width;    s->coded_height = height;    s->width        = AV_CEIL_RSHIFT(width,  s->lowres);    s->height       = AV_CEIL_RSHIFT(height, s->lowres);     return ret;} int ff_set_sar(AVCodecContext *avctx, AVRational sar){    int ret = av_image_check_sar(avctx->width, avctx->height, sar);     if (ret < 0) {        av_log(avctx, AV_LOG_WARNING, "ignoring invalid SAR: %d/%d\n",               sar.num, sar.den);        avctx->sample_aspect_ratio = (AVRational){ 0, 1 };        return ret;    } else {        avctx->sample_aspect_ratio = sar;    }    return 0;} int ff_side_data_update_matrix_encoding(AVFrame *frame,                                        enum AVMatrixEncoding matrix_encoding){    AVFrameSideData *side_data;    enum AVMatrixEncoding *data;     side_data = av_frame_get_side_data(frame, AV_FRAME_DATA_MATRIXENCODING);    if (!side_data)        side_data = av_frame_new_side_data(frame, AV_FRAME_DATA_MATRIXENCODING,                                           sizeof(enum AVMatrixEncoding));     if (!side_data)        return AVERROR(ENOMEM);     data  = (enum AVMatrixEncoding*)side_data->data;    *data = matrix_encoding;     return 0;} void avcodec_align_dimensions2(AVCodecContext *s, int *width, int *height,                               int linesize_align[AV_NUM_DATA_POINTERS]){    int i;    int w_align = 1;    int h_align = 1;    AVPixFmtDescriptor const *desc = av_pix_fmt_desc_get(s->pix_fmt);     if (desc) {        w_align = 1 << desc->log2_chroma_w;        h_align = 1 << desc->log2_chroma_h;    }     switch (s->pix_fmt) {    case AV_PIX_FMT_YUV420P:    case AV_PIX_FMT_YUYV422:    case AV_PIX_FMT_YVYU422:    case AV_PIX_FMT_UYVY422:    case AV_PIX_FMT_YUV422P:    case AV_PIX_FMT_YUV440P:    case AV_PIX_FMT_YUV444P:    case AV_PIX_FMT_GBRP:    case AV_PIX_FMT_GBRAP:    case AV_PIX_FMT_GRAY8:    case AV_PIX_FMT_GRAY16BE:    case AV_PIX_FMT_GRAY16LE:    case AV_PIX_FMT_YUVJ420P:    case AV_PIX_FMT_YUVJ422P:    case AV_PIX_FMT_YUVJ440P:    case AV_PIX_FMT_YUVJ444P:    case AV_PIX_FMT_YUVA420P:    case AV_PIX_FMT_YUVA422P:    case AV_PIX_FMT_YUVA444P:    case AV_PIX_FMT_YUV420P9LE:    case AV_PIX_FMT_YUV420P9BE:    case AV_PIX_FMT_YUV420P10LE:    case AV_PIX_FMT_YUV420P10BE:    case AV_PIX_FMT_YUV420P12LE:    case AV_PIX_FMT_YUV420P12BE:    case AV_PIX_FMT_YUV420P14LE:    case AV_PIX_FMT_YUV420P14BE:    case AV_PIX_FMT_YUV420P16LE:    case AV_PIX_FMT_YUV420P16BE:    case AV_PIX_FMT_YUVA420P9LE:    case AV_PIX_FMT_YUVA420P9BE:    case AV_PIX_FMT_YUVA420P10LE:    case AV_PIX_FMT_YUVA420P10BE:    case AV_PIX_FMT_YUVA420P16LE:    case AV_PIX_FMT_YUVA420P16BE:    case AV_PIX_FMT_YUV422P9LE:    case AV_PIX_FMT_YUV422P9BE:    case AV_PIX_FMT_YUV422P10LE:    case AV_PIX_FMT_YUV422P10BE:    case AV_PIX_FMT_YUV422P12LE:    case AV_PIX_FMT_YUV422P12BE:    case AV_PIX_FMT_YUV422P14LE:    case AV_PIX_FMT_YUV422P14BE:    case AV_PIX_FMT_YUV422P16LE:    case AV_PIX_FMT_YUV422P16BE:    case AV_PIX_FMT_YUVA422P9LE:    case AV_PIX_FMT_YUVA422P9BE:    case AV_PIX_FMT_YUVA422P10LE:    case AV_PIX_FMT_YUVA422P10BE:    case AV_PIX_FMT_YUVA422P12LE:    case AV_PIX_FMT_YUVA422P12BE:    case AV_PIX_FMT_YUVA422P16LE:    case AV_PIX_FMT_YUVA422P16BE:    case AV_PIX_FMT_YUV440P10LE:    case AV_PIX_FMT_YUV440P10BE:    case AV_PIX_FMT_YUV440P12LE:    case AV_PIX_FMT_YUV440P12BE:    case AV_PIX_FMT_YUV444P9LE:    case AV_PIX_FMT_YUV444P9BE:    case AV_PIX_FMT_YUV444P10LE:    case AV_PIX_FMT_YUV444P10BE:    case AV_PIX_FMT_YUV444P12LE:    case AV_PIX_FMT_YUV444P12BE:    case AV_PIX_FMT_YUV444P14LE:    case AV_PIX_FMT_YUV444P14BE:    case AV_PIX_FMT_YUV444P16LE:    case AV_PIX_FMT_YUV444P16BE:    case AV_PIX_FMT_YUVA444P9LE:    case AV_PIX_FMT_YUVA444P9BE:    case AV_PIX_FMT_YUVA444P10LE:    case AV_PIX_FMT_YUVA444P10BE:    case AV_PIX_FMT_YUVA444P12LE:    case AV_PIX_FMT_YUVA444P12BE:    case AV_PIX_FMT_YUVA444P16LE:    case AV_PIX_FMT_YUVA444P16BE:    case AV_PIX_FMT_GBRP9LE:    case AV_PIX_FMT_GBRP9BE:    case AV_PIX_FMT_GBRP10LE:    case AV_PIX_FMT_GBRP10BE:    case AV_PIX_FMT_GBRP12LE:    case AV_PIX_FMT_GBRP12BE:    case AV_PIX_FMT_GBRP14LE:    case AV_PIX_FMT_GBRP14BE:    case AV_PIX_FMT_GBRP16LE:    case AV_PIX_FMT_GBRP16BE:    case AV_PIX_FMT_GBRAP12LE:    case AV_PIX_FMT_GBRAP12BE:    case AV_PIX_FMT_GBRAP16LE:    case AV_PIX_FMT_GBRAP16BE:        w_align = 16; //FIXME assume 16 pixel per macroblock        h_align = 16 * 2; // interlaced needs 2 macroblocks height        break;    case AV_PIX_FMT_YUV411P:    case AV_PIX_FMT_YUVJ411P:    case AV_PIX_FMT_UYYVYY411:        w_align = 32;        h_align = 16 * 2;        break;    case AV_PIX_FMT_YUV410P:        if (s->codec_id == AV_CODEC_ID_SVQ1) {            w_align = 64;            h_align = 64;        }        break;    case AV_PIX_FMT_RGB555:        if (s->codec_id == AV_CODEC_ID_RPZA) {            w_align = 4;            h_align = 4;        }        if (s->codec_id == AV_CODEC_ID_INTERPLAY_VIDEO) {            w_align = 8;            h_align = 8;        }        break;    case AV_PIX_FMT_PAL8:    case AV_PIX_FMT_BGR8:    case AV_PIX_FMT_RGB8:        if (s->codec_id == AV_CODEC_ID_SMC ||            s->codec_id == AV_CODEC_ID_CINEPAK) {            w_align = 4;            h_align = 4;        }        if (s->codec_id == AV_CODEC_ID_JV ||            s->codec_id == AV_CODEC_ID_INTERPLAY_VIDEO) {            w_align = 8;            h_align = 8;        }        break;    case AV_PIX_FMT_BGR24:        if ((s->codec_id == AV_CODEC_ID_MSZH) ||            (s->codec_id == AV_CODEC_ID_ZLIB)) {            w_align = 4;            h_align = 4;        }        break;    case AV_PIX_FMT_RGB24:        if (s->codec_id == AV_CODEC_ID_CINEPAK) {            w_align = 4;            h_align = 4;        }        break;    default:        break;    }     if (s->codec_id == AV_CODEC_ID_IFF_ILBM) {        w_align = FFMAX(w_align, 8);    }     *width  = FFALIGN(*width, w_align);    *height = FFALIGN(*height, h_align);    if (s->codec_id == AV_CODEC_ID_H264 || s->lowres ||        s->codec_id == AV_CODEC_ID_VP5  || s->codec_id == AV_CODEC_ID_VP6 ||        s->codec_id == AV_CODEC_ID_VP6F || s->codec_id == AV_CODEC_ID_VP6A    ) {        // some of the optimized chroma MC reads one line too much        // which is also done in mpeg decoders with lowres > 0        *height += 2;         // H.264 uses edge emulation for out of frame motion vectors, for this        // it requires a temporary area large enough to hold a 21x21 block,        // increasing witdth ensure that the temporary area is large enough,        // the next rounded up width is 32        *width = FFMAX(*width, 32);    }     for (i = 0; i < 4; i++)        linesize_align[i] = STRIDE_ALIGN;} void avcodec_align_dimensions(AVCodecContext *s, int *width, int *height){    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(s->pix_fmt);    int chroma_shift = desc->log2_chroma_w;    int linesize_align[AV_NUM_DATA_POINTERS];    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);} int avcodec_enum_to_chroma_pos(int *xpos, int *ypos, enum AVChromaLocation pos){    if (pos <= AVCHROMA_LOC_UNSPECIFIED || pos >= AVCHROMA_LOC_NB)        return AVERROR(EINVAL);    pos--;     *xpos = (pos&1) * 128;    *ypos = ((pos>>1)^(pos<4)) * 128;     return 0;} enum AVChromaLocation avcodec_chroma_pos_to_enum(int xpos, int ypos){    int pos, xout, yout;     for (pos = AVCHROMA_LOC_UNSPECIFIED + 1; pos < AVCHROMA_LOC_NB; pos++) {        if (avcodec_enum_to_chroma_pos(&xout, &yout, pos) == 0 && xout == xpos && yout == ypos)            return pos;    }    return AVCHROMA_LOC_UNSPECIFIED;} int avcodec_fill_audio_frame(AVFrame *frame, int nb_channels,                             enum AVSampleFormat sample_fmt, const uint8_t *buf,                             int buf_size, int align){    int ch, planar, needed_size, ret = 0;     needed_size = av_samples_get_buffer_size(NULL, nb_channels,                                             frame->nb_samples, sample_fmt,                                             align);    if (buf_size < needed_size)        return AVERROR(EINVAL);     planar = av_sample_fmt_is_planar(sample_fmt);    if (planar && nb_channels > AV_NUM_DATA_POINTERS) {        if (!(frame->extended_data = av_mallocz_array(nb_channels,                                                sizeof(*frame->extended_data))))            return AVERROR(ENOMEM);    } else {        frame->extended_data = frame->data;    }     if ((ret = av_samples_fill_arrays(frame->extended_data, &frame->linesize[0],                                      (uint8_t *)(intptr_t)buf, nb_channels, frame->nb_samples,                                      sample_fmt, align)) < 0) {        if (frame->extended_data != frame->data)            av_freep(&frame->extended_data);        return ret;    }    if (frame->extended_data != frame->data) {        for (ch = 0; ch < AV_NUM_DATA_POINTERS; ch++)            frame->data[ch] = frame->extended_data[ch];    }     return ret;} void ff_color_frame(AVFrame *frame, const int c[4]){    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(frame->format);    int p, y;     av_assert0(desc->flags & AV_PIX_FMT_FLAG_PLANAR);     for (p = 0; p<desc->nb_components; p++) {        uint8_t *dst = frame->data[p];        int is_chroma = p == 1 || p == 2;        int bytes  = is_chroma ? AV_CEIL_RSHIFT(frame->width,  desc->log2_chroma_w) : frame->width;        int height = is_chroma ? AV_CEIL_RSHIFT(frame->height, desc->log2_chroma_h) : frame->height;        if (desc->comp[0].depth >= 9) {            ((uint16_t*)dst)[0] = c[p];            av_memcpy_backptr(dst + 2, 2, bytes - 2);            dst += frame->linesize[p];            for (y = 1; y < height; y++) {                memcpy(dst, frame->data[p], 2*bytes);                dst += frame->linesize[p];            }        } else {            for (y = 0; y < height; y++) {                memset(dst, c[p], bytes);                dst += frame->linesize[p];            }        }    }} int avcodec_default_execute(AVCodecContext *c, int (*func)(AVCodecContext *c2, void *arg2), void *arg, int *ret, int count, int size){    int i;     for (i = 0; i < count; i++) {        int r = func(c, (char *)arg + i * size);        if (ret)            ret[i] = r;    }    emms_c();    return 0;} int avcodec_default_execute2(AVCodecContext *c, int (*func)(AVCodecContext *c2, void *arg2, int jobnr, int threadnr), void *arg, int *ret, int count){    int i;     for (i = 0; i < count; i++) {        int r = func(c, arg, i, 0);        if (ret)            ret[i] = r;    }    emms_c();    return 0;} enum AVPixelFormat avpriv_find_pix_fmt(const PixelFormatTag *tags,                                       unsigned int fourcc){    while (tags->pix_fmt >= 0) {        if (tags->fourcc == fourcc)            return tags->pix_fmt;        tags++;    }    return AV_PIX_FMT_NONE;} #if FF_API_CODEC_GET_SETMAKE_ACCESSORS(AVCodecContext, codec, AVRational, pkt_timebase)MAKE_ACCESSORS(AVCodecContext, codec, const AVCodecDescriptor *, codec_descriptor)MAKE_ACCESSORS(AVCodecContext, codec, int, lowres)MAKE_ACCESSORS(AVCodecContext, codec, int, seek_preroll)MAKE_ACCESSORS(AVCodecContext, codec, uint16_t*, chroma_intra_matrix) unsigned av_codec_get_codec_properties(const AVCodecContext *codec){    return codec->properties;} int av_codec_get_max_lowres(const AVCodec *codec){    return codec->max_lowres;}#endif int avpriv_codec_get_cap_skip_frame_fill_param(const AVCodec *codec){    return !!(codec->caps_internal & FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM);}

Lines 1–500 of 2352.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t