* Copyright (c) 2001 Fabrice Bellard
* Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
static int volatile entangled_thread_counter=0;
static int (*ff_lockmgr_cb)(void **mutex, enum AVLockOp op);
static void *codec_mutex;
+static void *avformat_mutex;
void *av_fast_realloc(void *ptr, unsigned int *size, size_t min_size)
{
case PIX_FMT_YUV444P9BE:
case PIX_FMT_YUV444P10LE:
case PIX_FMT_YUV444P10BE:
+ case PIX_FMT_GBR24P:
w_align= 16; //FIXME check for non mpeg style codecs and use less alignment
h_align= 16;
- if(s->codec_id == CODEC_ID_MPEG2VIDEO || s->codec_id == CODEC_ID_MJPEG || s->codec_id == CODEC_ID_AMV || s->codec_id == CODEC_ID_THP || s->codec_id == CODEC_ID_H264)
+ if(s->codec_id == CODEC_ID_MPEG2VIDEO || s->codec_id == CODEC_ID_MJPEG || s->codec_id == CODEC_ID_AMV || s->codec_id == CODEC_ID_THP || s->codec_id == CODEC_ID_H264 || s->codec_id == CODEC_ID_PRORES)
h_align= 32; // interlaced is rounded up to 2 MBs
break;
case PIX_FMT_YUV411P:
#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) {
+ s->codec_id == CODEC_ID_VP6A || s->codec_id == CODEC_ID_DIRAC) {
linesize_align[0] =
linesize_align[1] =
linesize_align[2] = 16;
*width=FFALIGN(*width, align);
}
+void ff_init_buffer_info(AVCodecContext *s, AVFrame *pic)
+{
+ if (s->pkt) {
+ pic->pkt_pts = s->pkt->pts;
+ pic->pkt_pos = s->pkt->pos;
+ } else {
+ pic->pkt_pts = AV_NOPTS_VALUE;
+ pic->pkt_pos = -1;
+ }
+ pic->reordered_opaque= s->reordered_opaque;
+ pic->sample_aspect_ratio = s->sample_aspect_ratio;
+ pic->width = s->width;
+ pic->height = s->height;
+ pic->format = s->pix_fmt;
+}
+
int avcodec_default_get_buffer(AVCodecContext *s, AVFrame *pic){
int i;
int w= s->width;
}
s->internal_buffer_count++;
- if(s->pkt) pic->pkt_pts= s->pkt->pts;
- else pic->pkt_pts= AV_NOPTS_VALUE;
+ if (s->pkt) {
+ pic->pkt_pts = s->pkt->pts;
+ pic->pkt_pos = s->pkt->pos;
+ } else {
+ pic->pkt_pts = AV_NOPTS_VALUE;
+ pic->pkt_pos = -1;
+ }
pic->reordered_opaque= s->reordered_opaque;
+ pic->sample_aspect_ratio = s->sample_aspect_ratio;
+ pic->width = s->width;
+ pic->height = s->height;
+ pic->format = s->pix_fmt;
if(s->debug&FF_DEBUG_BUFFERS)
av_log(s, AV_LOG_DEBUG, "default_get_buffer called on pic %p, %d buffers used\n", pic, s->internal_buffer_count);
void avcodec_get_frame_defaults(AVFrame *pic){
memset(pic, 0, sizeof(AVFrame));
- pic->pts= AV_NOPTS_VALUE;
+ pic->pts = pic->best_effort_timestamp = AV_NOPTS_VALUE;
+ pic->pkt_pos = -1;
pic->key_frame= 1;
+ pic->sample_aspect_ratio = (AVRational){0, 1};
+ pic->format = -1; /* unknown */
}
AVFrame *avcodec_alloc_frame(void){
return pic;
}
+static void avcodec_get_subtitle_defaults(AVSubtitle *sub)
+{
+ memset(sub, 0, sizeof(*sub));
+ sub->pts = AV_NOPTS_VALUE;
+}
+
#if FF_API_AVCODEC_OPEN
int attribute_align_arg avcodec_open(AVCodecContext *avctx, AVCodec *codec)
{
avctx->error_recognition, avctx->err_recognition);
#endif
+ if (!HAVE_THREADS)
+ av_log(avctx, AV_LOG_WARNING, "Warning: not compiled with thread support, using thread emulation\n");
+
if (HAVE_THREADS && !avctx->thread_opaque) {
ret = ff_thread_init(avctx);
if (ret < 0) {
}
}
- if (avctx->codec->max_lowres < avctx->lowres) {
+ if (avctx->codec->max_lowres < avctx->lowres || avctx->lowres < 0) {
av_log(avctx, AV_LOG_ERROR, "The maximum value for lowres supported by the decoder is %d\n",
avctx->codec->max_lowres);
ret = AVERROR(EINVAL);
}
}
+ avctx->pts_correction_num_faulty_pts =
+ avctx->pts_correction_num_faulty_dts = 0;
+ avctx->pts_correction_last_pts =
+ avctx->pts_correction_last_dts = INT64_MIN;
+
if(avctx->codec->init && !(avctx->active_thread_type&FF_THREAD_FRAME)){
ret = avctx->codec->init(avctx);
if (ret < 0) {
goto free_and_end;
}
}
+
+ ret=0;
end:
entangled_thread_counter--;
av_log(avctx, AV_LOG_ERROR, "start_display_time must be 0.\n");
return -1;
}
- if(sub->num_rects == 0 || !sub->rects)
- return -1;
+
ret = avctx->codec->encode(avctx, buf, buf_size, sub);
avctx->frame_number++;
return ret;
}
+/**
+ * Attempt to guess proper monotonic timestamps for decoded video frames
+ * which might have incorrect times. Input timestamps may wrap around, in
+ * which case the output will as well.
+ *
+ * @param pts the pts field of the decoded AVPacket, as passed through
+ * AVFrame.pkt_pts
+ * @param dts the dts field of the decoded AVPacket
+ * @return one of the input values, may be AV_NOPTS_VALUE
+ */
+static int64_t guess_correct_pts(AVCodecContext *ctx,
+ int64_t reordered_pts, int64_t dts)
+{
+ int64_t pts = AV_NOPTS_VALUE;
+
+ if (dts != AV_NOPTS_VALUE) {
+ ctx->pts_correction_num_faulty_dts += dts <= ctx->pts_correction_last_dts;
+ ctx->pts_correction_last_dts = dts;
+ }
+ if (reordered_pts != AV_NOPTS_VALUE) {
+ ctx->pts_correction_num_faulty_pts += reordered_pts <= ctx->pts_correction_last_pts;
+ ctx->pts_correction_last_pts = reordered_pts;
+ }
+ if ((ctx->pts_correction_num_faulty_pts<=ctx->pts_correction_num_faulty_dts || dts == AV_NOPTS_VALUE)
+ && reordered_pts != AV_NOPTS_VALUE)
+ pts = reordered_pts;
+ else
+ pts = dts;
+
+ return pts;
+}
+
int attribute_align_arg avcodec_decode_video2(AVCodecContext *avctx, AVFrame *picture,
int *got_picture_ptr,
AVPacket *avpkt)
if((avctx->coded_width||avctx->coded_height) && av_image_check_size(avctx->coded_width, avctx->coded_height, 0, avctx))
return -1;
- avctx->pkt = avpkt;
-
if((avctx->codec->capabilities & CODEC_CAP_DELAY) || avpkt->size || (avctx->active_thread_type&FF_THREAD_FRAME)){
+ av_packet_split_side_data(avpkt);
+ avctx->pkt = avpkt;
if (HAVE_THREADS && avctx->active_thread_type&FF_THREAD_FRAME)
ret = ff_thread_decode_frame(avctx, picture, got_picture_ptr,
avpkt);
ret = avctx->codec->decode(avctx, picture, got_picture_ptr,
avpkt);
picture->pkt_dts= avpkt->dts;
+
+ if(!avctx->has_b_frames){
+ picture->pkt_pos= avpkt->pos;
+ }
+ //FIXME these should be under if(!avctx->has_b_frames)
+ if (!picture->sample_aspect_ratio.num)
+ picture->sample_aspect_ratio = avctx->sample_aspect_ratio;
+ if (!picture->width)
+ picture->width = avctx->width;
+ if (!picture->height)
+ picture->height = avctx->height;
+ if (picture->format == PIX_FMT_NONE)
+ picture->format = avctx->pix_fmt;
}
emms_c(); //needed to avoid an emms_c() call before every return;
- if (*got_picture_ptr)
+
+ if (*got_picture_ptr){
avctx->frame_number++;
+ picture->best_effort_timestamp = guess_correct_pts(avctx,
+ picture->pkt_pts,
+ picture->pkt_dts);
+ }
}else
ret= 0;
avctx->pkt = avpkt;
*got_sub_ptr = 0;
+ avcodec_get_subtitle_defaults(sub);
ret = avctx->codec->decode(avctx, sub, got_sub_ptr, avpkt);
if (*got_sub_ptr)
avctx->frame_number++;
return 0;
}
+static enum CodecID remap_deprecated_codec_id(enum CodecID id)
+{
+ switch(id){
+ case CODEC_ID_G723_1_DEPRECATED : return CODEC_ID_G723_1;
+ case CODEC_ID_G729_DEPRECATED : return CODEC_ID_G729;
+ case CODEC_ID_UTVIDEO_DEPRECATED: return CODEC_ID_UTVIDEO;
+ default : return id;
+ }
+}
+
AVCodec *avcodec_find_encoder(enum CodecID id)
{
AVCodec *p, *experimental=NULL;
p = first_avcodec;
+ id= remap_deprecated_codec_id(id);
while (p) {
if (p->encode != NULL && p->id == id) {
if (p->capabilities & CODEC_CAP_EXPERIMENTAL && !experimental) {
AVCodec *avcodec_find_decoder(enum CodecID id)
{
- AVCodec *p;
+ AVCodec *p, *experimental=NULL;
p = first_avcodec;
+ id= remap_deprecated_codec_id(id);
while (p) {
- if (p->decode != NULL && p->id == id)
- return p;
+ if (p->decode != 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_decoder_by_name(const char *name)
return bit_rate;
}
+const char *avcodec_get_name(enum CodecID id)
+{
+ AVCodec *codec;
+
+#if !CONFIG_SMALL
+ switch (id) {
+#include "libavcodec/codec_names.h"
+ }
+ av_log(NULL, AV_LOG_WARNING, "Codec 0x%x is not in the full list.\n", id);
+#endif
+ codec = avcodec_find_decoder(id);
+ if (codec)
+ return codec->name;
+ codec = avcodec_find_encoder(id);
+ if (codec)
+ return codec->name;
+ return "unknown_codec";
+}
+
size_t av_get_codec_tag_string(char *buf, size_t buf_size, unsigned int codec_tag)
{
int i, len, ret = 0;
void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode)
{
+ const char *codec_type;
const char *codec_name;
const char *profile = NULL;
AVCodec *p;
- char buf1[32];
int bitrate;
AVRational display_aspect_ratio;
- if (encode)
- p = avcodec_find_encoder(enc->codec_id);
- else
- p = avcodec_find_decoder(enc->codec_id);
-
- if (p) {
- codec_name = p->name;
- profile = av_get_profile_name(p, enc->profile);
- } else if (enc->codec_id == CODEC_ID_MPEG2TS) {
- /* fake mpeg2 transport stream codec (currently not
- registered) */
- codec_name = "mpeg2ts";
- } else if (enc->codec_name[0] != '\0') {
- codec_name = enc->codec_name;
- } else {
- /* output avi tags */
+ if (!buf || buf_size <= 0)
+ return;
+ codec_type = av_get_media_type_string(enc->codec_type);
+ codec_name = avcodec_get_name(enc->codec_id);
+ if (enc->profile != FF_PROFILE_UNKNOWN) {
+ p = encode ? avcodec_find_encoder(enc->codec_id) :
+ avcodec_find_decoder(enc->codec_id);
+ if (p)
+ profile = av_get_profile_name(p, enc->profile);
+ }
+
+ snprintf(buf, buf_size, "%s: %s%s", codec_type ? codec_type : "unknown",
+ codec_name, enc->mb_decision ? " (hq)" : "");
+ buf[0] ^= 'a' ^ 'A'; /* first letter in uppercase */
+ if (profile)
+ snprintf(buf + strlen(buf), buf_size - strlen(buf), " (%s)", profile);
+ if (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;
+ snprintf(buf + strlen(buf), buf_size - strlen(buf),
+ " (%s / 0x%04X)", tag_buf, enc->codec_tag);
}
-
switch(enc->codec_type) {
case AVMEDIA_TYPE_VIDEO:
- snprintf(buf, buf_size,
- "Video: %s%s",
- codec_name, enc->mb_decision ? " (hq)" : "");
- if (profile)
- snprintf(buf + strlen(buf), buf_size - strlen(buf),
- " (%s)", profile);
if (enc->pix_fmt != PIX_FMT_NONE) {
snprintf(buf + strlen(buf), buf_size - strlen(buf),
", %s",
enc->height*enc->sample_aspect_ratio.den,
1024*1024);
snprintf(buf + strlen(buf), buf_size - strlen(buf),
- " [PAR %d:%d DAR %d:%d]",
+ " [SAR %d:%d DAR %d:%d]",
enc->sample_aspect_ratio.num, enc->sample_aspect_ratio.den,
display_aspect_ratio.num, display_aspect_ratio.den);
}
}
break;
case AVMEDIA_TYPE_AUDIO:
- snprintf(buf, buf_size,
- "Audio: %s",
- codec_name);
- if (profile)
- snprintf(buf + strlen(buf), buf_size - strlen(buf),
- " (%s)", profile);
if (enc->sample_rate) {
snprintf(buf + strlen(buf), buf_size - strlen(buf),
", %d Hz", enc->sample_rate);
", %s", av_get_sample_fmt_name(enc->sample_fmt));
}
break;
- case AVMEDIA_TYPE_DATA:
- snprintf(buf, buf_size, "Data: %s", codec_name);
- break;
- case AVMEDIA_TYPE_SUBTITLE:
- snprintf(buf, buf_size, "Subtitle: %s", codec_name);
- break;
- case AVMEDIA_TYPE_ATTACHMENT:
- snprintf(buf, buf_size, "Attachment: %s", codec_name);
- break;
default:
- snprintf(buf, buf_size, "Invalid Codec type %d", enc->codec_type);
return;
}
if (encode) {
const char *avcodec_configuration(void)
{
- return LIBAV_CONFIGURATION;
+ return FFMPEG_CONFIGURATION;
}
const char *avcodec_license(void)
{
#define LICENSE_PREFIX "libavcodec license: "
- return LICENSE_PREFIX LIBAV_LICENSE + sizeof(LICENSE_PREFIX) - 1;
+ return LICENSE_PREFIX FFMPEG_LICENSE + sizeof(LICENSE_PREFIX) - 1;
}
void avcodec_flush_buffers(AVCodecContext *avctx)
void av_log_missing_feature(void *avc, const char *feature, int want_sample)
{
- av_log(avc, AV_LOG_WARNING, "%s not implemented. Update your Libav "
+ av_log(avc, AV_LOG_WARNING, "%s not implemented. Update your FFmpeg "
"version to the newest one from Git. If the problem still "
"occurs, it means that your file has a feature which has not "
"been implemented.\n", feature);
if (msg)
av_vlog(avc, AV_LOG_WARNING, msg, argument_list);
av_log(avc, AV_LOG_WARNING, "If you want to help, upload a sample "
- "of this file to ftp://upload.libav.org/incoming/ "
- "and contact the libav-devel mailing list.\n");
+ "of this file to ftp://upload.ffmpeg.org/MPlayer/incoming/ "
+ "and contact the ffmpeg-devel mailing list.\n");
va_end(argument_list);
}
if (ff_lockmgr_cb) {
if (ff_lockmgr_cb(&codec_mutex, AV_LOCK_DESTROY))
return -1;
+ if (ff_lockmgr_cb(&avformat_mutex, AV_LOCK_DESTROY))
+ return -1;
}
ff_lockmgr_cb = cb;
if (ff_lockmgr_cb) {
if (ff_lockmgr_cb(&codec_mutex, AV_LOCK_CREATE))
return -1;
+ if (ff_lockmgr_cb(&avformat_mutex, AV_LOCK_CREATE))
+ return -1;
+ }
+ return 0;
+}
+
+int avpriv_lock_avformat(void)
+{
+ if (ff_lockmgr_cb) {
+ if ((*ff_lockmgr_cb)(&avformat_mutex, AV_LOCK_OBTAIN))
+ return -1;
+ }
+ return 0;
+}
+
+int avpriv_unlock_avformat(void)
+{
+ if (ff_lockmgr_cb) {
+ if ((*ff_lockmgr_cb)(&avformat_mutex, AV_LOCK_RELEASE))
+ return -1;
}
return 0;
}
int ff_thread_get_buffer(AVCodecContext *avctx, AVFrame *f)
{
f->owner = avctx;
+
+ ff_init_buffer_info(avctx, f);
+
return avctx->get_buffer(avctx, f);
}
enum AVMediaType avcodec_get_type(enum CodecID codec_id)
{
+ AVCodec *c= avcodec_find_decoder(codec_id);
+ if(!c)
+ c= avcodec_find_encoder(codec_id);
+ if(c)
+ return c->type;
+
if (codec_id <= CODEC_ID_NONE)
return AVMEDIA_TYPE_UNKNOWN;
else if (codec_id < CODEC_ID_FIRST_AUDIO)