X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Futils.c;h=77811b0f91fc7a80598b12a7d7df76ded7f7aae8;hb=f2193569a548fde059eb877661ec8a224c9fae1f;hp=1685b4d196f51b0034f6e91b205a56b3ced49727;hpb=15c481614bb410cfa147f8051024d42b01eadff8;p=ffmpeg diff --git a/libavcodec/utils.c b/libavcodec/utils.c index 1685b4d196f..77811b0f91f 100644 --- a/libavcodec/utils.c +++ b/libavcodec/utils.c @@ -33,6 +33,7 @@ #include "libavutil/imgutils.h" #include "libavutil/samplefmt.h" #include "libavutil/dict.h" +#include "libavutil/avassert.h" #include "avcodec.h" #include "dsputil.h" #include "libavutil/opt.h" @@ -40,6 +41,7 @@ #include "thread.h" #include "audioconvert.h" #include "internal.h" +#include "bytestream.h" #include #include #include @@ -166,10 +168,8 @@ void avcodec_align_dimensions2(AVCodecContext *s, int *width, int *height, case PIX_FMT_GBRP9BE: case PIX_FMT_GBRP10LE: case PIX_FMT_GBRP10BE: - 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 || s->codec_id == CODEC_ID_PRORES) - h_align= 32; // interlaced is rounded up to 2 MBs + w_align = 16; //FIXME assume 16 pixel per macroblock + h_align = 16 * 2; // interlaced needs 2 macroblocks height break; case PIX_FMT_YUV411P: case PIX_FMT_UYYVYY411: @@ -372,7 +372,6 @@ static int video_get_buffer(AVCodecContext *s, AVFrame *pic) int w= s->width; int h= s->height; InternalBuffer *buf; - int *picture_number; AVCodecInternal *avci = s->internal; if(pic->data[0]!=NULL) { @@ -393,8 +392,6 @@ static int video_get_buffer(AVCodecContext *s, AVFrame *pic) } buf = &avci->buffer[avci->buffer_count]; - picture_number = &(avci->buffer[INTERNAL_BUFFER_SIZE]).last_pic_num; //FIXME ugly hack - (*picture_number)++; if(buf->base[0] && (buf->width != w || buf->height != h || buf->pix_fmt != s->pix_fmt)){ if(s->active_thread_type&FF_THREAD_FRAME) { @@ -408,10 +405,7 @@ static int video_get_buffer(AVCodecContext *s, AVFrame *pic) } } - if(buf->base[0]){ - pic->age= *picture_number - buf->last_pic_num; - buf->last_pic_num= *picture_number; - }else{ + if (!buf->base[0]) { int h_chroma_shift, v_chroma_shift; int size[4] = {0}; int tmpsize; @@ -450,7 +444,6 @@ static int video_get_buffer(AVCodecContext *s, AVFrame *pic) size[i] = picture.data[i+1] - picture.data[i]; size[i] = tmpsize - (picture.data[i] - picture.data[0]); - buf->last_pic_num= -256*256*256*64; memset(buf->base, 0, sizeof(buf->base)); memset(buf->data, 0, sizeof(buf->data)); @@ -479,7 +472,6 @@ static int video_get_buffer(AVCodecContext *s, AVFrame *pic) 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; @@ -544,7 +536,8 @@ void avcodec_default_release_buffer(AVCodecContext *s, AVFrame *pic){ avci->buffer_count--; last = &avci->buffer[avci->buffer_count]; - FFSWAP(InternalBuffer, *buf, *last); + if (buf != last) + FFSWAP(InternalBuffer, *buf, *last); } for (i = 0; i < AV_NUM_DATA_POINTERS; i++) { @@ -625,7 +618,7 @@ enum PixelFormat avcodec_default_get_format(struct AVCodecContext *s, const enum void avcodec_get_frame_defaults(AVFrame *pic){ memset(pic, 0, sizeof(AVFrame)); - pic->pts = pic->best_effort_timestamp = AV_NOPTS_VALUE; + pic->pts = pic->pkt_dts = pic->pkt_pts = pic->best_effort_timestamp = AV_NOPTS_VALUE; pic->pkt_pos = -1; pic->key_frame= 1; pic->sample_aspect_ratio = (AVRational){0, 1}; @@ -660,6 +653,9 @@ int attribute_align_arg avcodec_open2(AVCodecContext *avctx, AVCodec *codec, AVD int ret = 0; AVDictionary *tmp = NULL; + if (avctx->extradata_size < 0 || avctx->extradata_size >= FF_MAX_EXTRADATA_SIZE) + return AVERROR(EINVAL); + if (options) av_dict_copy(&tmp, *options, 0); @@ -748,7 +744,7 @@ int attribute_align_arg avcodec_open2(AVCodecContext *avctx, AVCodec *codec, AVD avctx->frame_number = 0; #if FF_API_ER - av_log(avctx, AV_LOG_DEBUG, "err{or,}_recognition separate: %d; %d\n", + av_log(avctx, AV_LOG_DEBUG, "err{or,}_recognition separate: %d; %X\n", avctx->error_recognition, avctx->err_recognition); switch(avctx->error_recognition){ case FF_ER_EXPLODE : avctx->err_recognition |= AV_EF_EXPLODE | AV_EF_COMPLIANT | AV_EF_CAREFUL; @@ -759,7 +755,7 @@ int attribute_align_arg avcodec_open2(AVCodecContext *avctx, AVCodec *codec, AVD case FF_ER_CAREFUL : avctx->err_recognition |= AV_EF_CAREFUL; } - av_log(avctx, AV_LOG_DEBUG, "err{or,}_recognition combined: %d; %d\n", + av_log(avctx, AV_LOG_DEBUG, "err{or,}_recognition combined: %d; %X\n", avctx->error_recognition, avctx->err_recognition); #endif @@ -772,6 +768,8 @@ int attribute_align_arg avcodec_open2(AVCodecContext *avctx, AVCodec *codec, AVD goto free_and_end; } } + if (!HAVE_THREADS && !(codec->capabilities & CODEC_CAP_AUTO_THREADS)) + avctx->thread_count = 1; 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", @@ -940,6 +938,48 @@ static int64_t guess_correct_pts(AVCodecContext *ctx, return pts; } +static void apply_param_change(AVCodecContext *avctx, AVPacket *avpkt) +{ + int size = 0; + const uint8_t *data; + uint32_t flags; + + if (!(avctx->codec->capabilities & CODEC_CAP_PARAM_CHANGE)) + return; + + data = av_packet_get_side_data(avpkt, AV_PKT_DATA_PARAM_CHANGE, &size); + if (!data || size < 4) + return; + flags = bytestream_get_le32(&data); + size -= 4; + if (size < 4) /* Required for any of the changes */ + return; + if (flags & AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_COUNT) { + avctx->channels = bytestream_get_le32(&data); + size -= 4; + } + if (flags & AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_LAYOUT) { + if (size < 8) + return; + avctx->channel_layout = bytestream_get_le64(&data); + size -= 8; + } + if (size < 4) + return; + if (flags & AV_SIDE_DATA_PARAM_CHANGE_SAMPLE_RATE) { + avctx->sample_rate = bytestream_get_le32(&data); + size -= 4; + } + if (flags & AV_SIDE_DATA_PARAM_CHANGE_DIMENSIONS) { + if (size < 8) + return; + avctx->width = bytestream_get_le32(&data); + avctx->height = bytestream_get_le32(&data); + avcodec_set_dimensions(avctx, avctx->width, avctx->height); + size -= 8; + } +} + int attribute_align_arg avcodec_decode_video2(AVCodecContext *avctx, AVFrame *picture, int *got_picture_ptr, AVPacket *avpkt) @@ -952,6 +992,7 @@ int attribute_align_arg avcodec_decode_video2(AVCodecContext *avctx, AVFrame *pi if((avctx->codec->capabilities & CODEC_CAP_DELAY) || avpkt->size || (avctx->active_thread_type&FF_THREAD_FRAME)){ av_packet_split_side_data(avpkt); + apply_param_change(avctx, avpkt); avctx->pkt = avpkt; if (HAVE_THREADS && avctx->active_thread_type&FF_THREAD_FRAME) ret = ff_thread_decode_frame(avctx, picture, got_picture_ptr, @@ -999,9 +1040,10 @@ int attribute_align_arg avcodec_decode_audio3(AVCodecContext *avctx, int16_t *sa int ret, got_frame = 0; if (avctx->get_buffer != avcodec_default_get_buffer) { - av_log(avctx, AV_LOG_ERROR, "A custom get_buffer() cannot be used with " + av_log(avctx, AV_LOG_ERROR, "Overriding custom get_buffer() for " "avcodec_decode_audio3()\n"); - return AVERROR(EINVAL); + avctx->get_buffer = avcodec_default_get_buffer; + avctx->release_buffer = avcodec_default_release_buffer; } ret = avcodec_decode_audio4(avctx, &frame, &got_frame, avpkt); @@ -1051,11 +1093,15 @@ int attribute_align_arg avcodec_decode_audio4(AVCodecContext *avctx, if ((avctx->codec->capabilities & CODEC_CAP_DELAY) || avpkt->size) { av_packet_split_side_data(avpkt); + apply_param_change(avctx, avpkt); + avctx->pkt = avpkt; ret = avctx->codec->decode(avctx, frame, got_frame_ptr, avpkt); if (ret >= 0 && *got_frame_ptr) { avctx->frame_number++; frame->pkt_dts = avpkt->dts; + if (frame->format == AV_SAMPLE_FMT_NONE) + frame->format = avctx->sample_fmt; } } return ret; @@ -1373,6 +1419,13 @@ const char *av_get_profile_name(const AVCodec *codec, int profile) unsigned avcodec_version( void ) { + av_assert0(CODEC_ID_V410==164); + av_assert0(CODEC_ID_PCM_S8_PLANAR==65563); + av_assert0(CODEC_ID_ADPCM_G722==69660); + av_assert0(CODEC_ID_BMV_AUDIO==86071); + av_assert0(CODEC_ID_SRT==94216); + av_assert0(LIBAVCODEC_VERSION_MICRO >= 100); + return LIBAVCODEC_VERSION_INT; }