X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Futils.c;h=b5b04666502229b9c242131452511f3bb529bbdc;hb=9afb7061f938831248942050cfdb449e014ed427;hp=c84439972cc381a295a5095115d3e9789218a86e;hpb=0eea212943544d40f99b05571aa7159d78667154;p=ffmpeg diff --git a/libavcodec/utils.c b/libavcodec/utils.c index c84439972cc..b5b04666502 100644 --- a/libavcodec/utils.c +++ b/libavcodec/utils.c @@ -25,6 +25,7 @@ * utils. */ +#include "libavutil/avassert.h" #include "libavutil/avstring.h" #include "libavutil/crc.h" #include "libavutil/mathematics.h" @@ -40,6 +41,7 @@ #include "thread.h" #include "audioconvert.h" #include "internal.h" +#include "bytestream.h" #include #include #include @@ -78,18 +80,29 @@ void av_fast_malloc(void *ptr, unsigned int *size, size_t min_size) *size= min_size; } +void av_fast_padded_malloc(void *ptr, unsigned int *size, size_t min_size) +{ + void **p = ptr; + if (min_size > SIZE_MAX - FF_INPUT_BUFFER_PADDING_SIZE) { + av_freep(p); + *size = 0; + return; + } + av_fast_malloc(p, size, min_size + FF_INPUT_BUFFER_PADDING_SIZE); + if (*size) + memset((uint8_t *)*p + min_size, 0, FF_INPUT_BUFFER_PADDING_SIZE); +} + /* encoder management */ static AVCodec *first_avcodec = NULL; -AVCodec *av_codec_next(AVCodec *c){ +AVCodec *av_codec_next(const AVCodec *c) +{ if(c) return c->next; else return first_avcodec; } -#if !FF_API_AVCODEC_INIT -static -#endif -void avcodec_init(void) +static void avcodec_init(void) { static int initialized = 0; @@ -97,7 +110,17 @@ void avcodec_init(void) return; initialized = 1; - dsputil_static_init(); + ff_dsputil_static_init(); +} + +int av_codec_is_encoder(const AVCodec *codec) +{ + return codec && (codec->encode || codec->encode2); +} + +int av_codec_is_decoder(const AVCodec *codec) +{ + return codec && codec->decode; } void avcodec_register(AVCodec *codec) @@ -121,8 +144,8 @@ unsigned avcodec_get_edge_width(void) void avcodec_set_dimensions(AVCodecContext *s, int width, int height){ s->coded_width = width; s->coded_height= height; - s->width = -((-width )>>s->lowres); - s->height= -((-height)>>s->lowres); + s->width = width; + s->height = height; } #define INTERNAL_BUFFER_SIZE (32+1) @@ -166,10 +189,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) - 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: @@ -177,25 +198,25 @@ void avcodec_align_dimensions2(AVCodecContext *s, int *width, int *height, h_align=8; break; case PIX_FMT_YUV410P: - if(s->codec_id == CODEC_ID_SVQ1){ + if(s->codec_id == AV_CODEC_ID_SVQ1){ w_align=64; h_align=64; } case PIX_FMT_RGB555: - if(s->codec_id == CODEC_ID_RPZA){ + if(s->codec_id == AV_CODEC_ID_RPZA){ w_align=4; h_align=4; } case PIX_FMT_PAL8: case PIX_FMT_BGR8: case PIX_FMT_RGB8: - if(s->codec_id == CODEC_ID_SMC){ + if(s->codec_id == AV_CODEC_ID_SMC){ w_align=4; h_align=4; } break; case PIX_FMT_BGR24: - if((s->codec_id == CODEC_ID_MSZH) || (s->codec_id == CODEC_ID_ZLIB)){ + if((s->codec_id == AV_CODEC_ID_MSZH) || (s->codec_id == AV_CODEC_ID_ZLIB)){ w_align=4; h_align=4; } @@ -208,24 +229,11 @@ void avcodec_align_dimensions2(AVCodecContext *s, int *width, int *height, *width = FFALIGN(*width , w_align); *height= FFALIGN(*height, h_align); - if(s->codec_id == CODEC_ID_H264 || s->lowres) + if (s->codec_id == AV_CODEC_ID_H264) *height+=2; // some of the optimized chroma MC reads one line too much - // which is also done in mpeg decoders with lowres > 0 - for (i = 0; i < AV_NUM_DATA_POINTERS; i++) + for (i = 0; i < 4; i++) linesize_align[i] = 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) { - for (i = 0; i < AV_NUM_DATA_POINTERS; i++) - linesize_align[i] = 16; - } -#endif } void avcodec_align_dimensions(AVCodecContext *s, int *width, int *height){ @@ -240,21 +248,54 @@ void avcodec_align_dimensions(AVCodecContext *s, int *width, int *height){ *width=FFALIGN(*width, align); } +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(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], + buf, nb_channels, frame->nb_samples, + sample_fmt, align)) < 0) { + if (frame->extended_data != frame->data) + av_free(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; +} + static int audio_get_buffer(AVCodecContext *avctx, AVFrame *frame) { AVCodecInternal *avci = avctx->internal; InternalBuffer *buf; - int buf_size, ret, i, needs_extended_data; + int buf_size, ret; buf_size = av_samples_get_buffer_size(NULL, avctx->channels, frame->nb_samples, avctx->sample_fmt, - 32); + 0); if (buf_size < 0) return AVERROR(EINVAL); - needs_extended_data = av_sample_fmt_is_planar(avctx->sample_fmt) && - avctx->channels > AV_NUM_DATA_POINTERS; - /* allocate InternalBuffer if needed */ if (!avci->buffer) { avci->buffer = av_mallocz(sizeof(InternalBuffer)); @@ -286,53 +327,40 @@ static int audio_get_buffer(AVCodecContext *avctx, AVFrame *frame) /* if there is no previous buffer or the previous buffer cannot be used as-is, allocate a new buffer and/or rearrange the channel pointers */ if (!buf->extended_data) { - /* if the channel pointers will fit, just set extended_data to data, - otherwise allocate the extended_data channel pointers */ - if (needs_extended_data) { - buf->extended_data = av_mallocz(avctx->channels * - sizeof(*buf->extended_data)); - if (!buf->extended_data) + if (!buf->data[0]) { + if (!(buf->data[0] = av_mallocz(buf_size))) return AVERROR(ENOMEM); - } else { - buf->extended_data = buf->data; - } - - /* if there is a previous buffer and it is large enough, reuse it and - just fill-in new channel pointers and linesize, otherwise allocate - a new buffer */ - if (buf->extended_data[0]) { - ret = av_samples_fill_arrays(buf->extended_data, &buf->linesize[0], - buf->extended_data[0], avctx->channels, - frame->nb_samples, avctx->sample_fmt, - 32); - } else { - ret = av_samples_alloc(buf->extended_data, &buf->linesize[0], - avctx->channels, frame->nb_samples, - avctx->sample_fmt, 32); + buf->audio_data_size = buf_size; } - if (ret) + if ((ret = avcodec_fill_audio_frame(frame, avctx->channels, + avctx->sample_fmt, buf->data[0], + buf->audio_data_size, 0))) return ret; - /* if data was not used for extended_data, we need to copy as many of - the extended_data channel pointers as will fit */ - if (needs_extended_data) { - for (i = 0; i < AV_NUM_DATA_POINTERS; i++) - buf->data[i] = buf->extended_data[i]; - } - buf->audio_data_size = buf_size; - buf->nb_channels = avctx->channels; + if (frame->extended_data == frame->data) + buf->extended_data = buf->data; + else + buf->extended_data = frame->extended_data; + memcpy(buf->data, frame->data, sizeof(frame->data)); + buf->linesize[0] = frame->linesize[0]; + buf->nb_channels = avctx->channels; + } else { + /* copy InternalBuffer info to the AVFrame */ + frame->extended_data = buf->extended_data; + frame->linesize[0] = buf->linesize[0]; + memcpy(frame->data, buf->data, sizeof(frame->data)); } - /* copy InternalBuffer info to the AVFrame */ frame->type = FF_BUFFER_TYPE_INTERNAL; - frame->extended_data = buf->extended_data; - frame->linesize[0] = buf->linesize[0]; - memcpy(frame->data, buf->data, sizeof(frame->data)); if (avctx->pkt) frame->pkt_pts = avctx->pkt->pts; else frame->pkt_pts = AV_NOPTS_VALUE; frame->reordered_opaque = avctx->reordered_opaque; + frame->sample_rate = avctx->sample_rate; + frame->format = avctx->sample_fmt; + frame->channel_layout = avctx->channel_layout; + if (avctx->debug & FF_DEBUG_BUFFERS) av_log(avctx, AV_LOG_DEBUG, "default_get_buffer called on frame %p, " "internal audio buffer used\n", frame); @@ -346,7 +374,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) { @@ -367,25 +394,15 @@ 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) { - av_log_missing_feature(s, "Width/height changing with frame threads is", 0); - return -1; - } - for (i = 0; i < AV_NUM_DATA_POINTERS; 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; - }else{ + if (!buf->base[0]) { int h_chroma_shift, v_chroma_shift; int size[4] = {0}; int tmpsize; @@ -424,7 +441,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)); @@ -453,7 +469,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; @@ -464,6 +479,10 @@ static int video_get_buffer(AVCodecContext *s, AVFrame *pic) } pic->extended_data = pic->data; avci->buffer_count++; + pic->width = buf->width; + pic->height = buf->height; + pic->format = buf->pix_fmt; + pic->sample_aspect_ratio = s->sample_aspect_ratio; if(s->pkt) pic->pkt_pts= s->pkt->pts; else pic->pkt_pts= AV_NOPTS_VALUE; @@ -509,7 +528,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++) { @@ -536,6 +556,8 @@ int avcodec_default_reget_buffer(AVCodecContext *s, AVFrame *pic){ return s->get_buffer(s, pic); } + assert(s->pix_fmt == pic->format); + /* If internal buffer type return the same buffer */ if(pic->type == FF_BUFFER_TYPE_INTERNAL) { if(s->pkt) pic->pkt_pts= s->pkt->pts; @@ -592,6 +614,8 @@ void avcodec_get_frame_defaults(AVFrame *pic){ pic->pts= AV_NOPTS_VALUE; pic->key_frame= 1; + pic->sample_aspect_ratio = (AVRational){0, 1}; + pic->format = -1; /* unknown */ } AVFrame *avcodec_alloc_frame(void){ @@ -604,18 +628,29 @@ AVFrame *avcodec_alloc_frame(void){ return pic; } -#if FF_API_AVCODEC_OPEN -int attribute_align_arg avcodec_open(AVCodecContext *avctx, AVCodec *codec) -{ - return avcodec_open2(avctx, codec, NULL); -} -#endif - -int attribute_align_arg avcodec_open2(AVCodecContext *avctx, AVCodec *codec, AVDictionary **options) +int attribute_align_arg avcodec_open2(AVCodecContext *avctx, const AVCodec *codec, AVDictionary **options) { int ret = 0; AVDictionary *tmp = NULL; + if (avcodec_is_open(avctx)) + return 0; + + if ((!codec && !avctx->codec)) { + av_log(avctx, AV_LOG_ERROR, "No codec provided to avcodec_open2().\n"); + return AVERROR(EINVAL); + } + if ((codec && avctx->codec && codec != avctx->codec)) { + av_log(avctx, AV_LOG_ERROR, "This AVCodecContext was allocated for %s, " + "but %s passed to avcodec_open2().\n", avctx->codec->name, codec->name); + return AVERROR(EINVAL); + } + if (!codec) + codec = avctx->codec; + + if (avctx->extradata_size < 0 || avctx->extradata_size >= FF_MAX_EXTRADATA_SIZE) + return AVERROR(EINVAL); + if (options) av_dict_copy(&tmp, *options, 0); @@ -632,11 +667,6 @@ int attribute_align_arg avcodec_open2(AVCodecContext *avctx, AVCodec *codec, AVD goto end; } - if(avctx->codec || !codec) { - ret = AVERROR(EINVAL); - goto end; - } - avctx->internal = av_mallocz(sizeof(AVCodecInternal)); if (!avctx->internal) { ret = AVERROR(ENOMEM); @@ -677,7 +707,7 @@ int attribute_align_arg avcodec_open2(AVCodecContext *avctx, AVCodec *codec, AVD /* if the decoder init function was already called previously, free the already allocated subtitle_header before overwriting it */ - if (codec->decode) + if (av_codec_is_decoder(codec)) av_freep(&avctx->subtitle_header); #define SANE_NB_CHANNELS 128U @@ -688,7 +718,7 @@ int attribute_align_arg avcodec_open2(AVCodecContext *avctx, AVCodec *codec, AVD avctx->codec = codec; if ((avctx->codec_type == AVMEDIA_TYPE_UNKNOWN || avctx->codec_type == codec->type) && - avctx->codec_id == CODEC_ID_NONE) { + avctx->codec_id == AV_CODEC_ID_NONE) { avctx->codec_type = codec->type; avctx->codec_id = codec->id; } @@ -699,16 +729,12 @@ int attribute_align_arg avcodec_open2(AVCodecContext *avctx, AVCodec *codec, AVD goto free_and_end; } avctx->frame_number = 0; -#if FF_API_ER - - av_log(avctx, AV_LOG_DEBUG, "err{or,}_recognition separate: %d; %d\n", - avctx->error_recognition, avctx->err_recognition); - /* FF_ER_CAREFUL (==1) implies AV_EF_CRCCHECK (== 1<<1 - 1), - FF_ER_COMPLIANT (==2) implies AV_EF_{CRCCHECK,BITSTREAM} (== 1<<2 - 1), et cetera} */ - avctx->err_recognition |= (1<<(avctx->error_recognition-(avctx->error_recognition>=FF_ER_VERY_AGGRESSIVE))) - 1; - av_log(avctx, AV_LOG_DEBUG, "err{or,}_recognition combined: %d; %d\n", - avctx->error_recognition, avctx->err_recognition); -#endif + + if (avctx->codec_type == AVMEDIA_TYPE_AUDIO && + (!avctx->time_base.num || !avctx->time_base.den)) { + avctx->time_base.num = 1; + avctx->time_base.den = avctx->sample_rate; + } if (HAVE_THREADS && !avctx->thread_opaque) { ret = ff_thread_init(avctx); @@ -716,14 +742,10 @@ 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) { - 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); - goto free_and_end; - } - if (avctx->codec->encode) { + if (av_codec_is_encoder(avctx->codec)) { int i; if (avctx->codec->sample_fmts) { for (i = 0; avctx->codec->sample_fmts[i] != AV_SAMPLE_FMT_NONE; i++) @@ -735,6 +757,16 @@ int attribute_align_arg avcodec_open2(AVCodecContext *avctx, AVCodec *codec, AVD goto free_and_end; } } + if (avctx->codec->pix_fmts) { + for (i = 0; avctx->codec->pix_fmts[i] != PIX_FMT_NONE; i++) + if (avctx->pix_fmt == avctx->codec->pix_fmts[i]) + break; + if (avctx->codec->pix_fmts[i] == PIX_FMT_NONE) { + av_log(avctx, AV_LOG_ERROR, "Specified pix_fmt is not supported\n"); + ret = AVERROR(EINVAL); + goto free_and_end; + } + } if (avctx->codec->supported_samplerates) { for (i = 0; avctx->codec->supported_samplerates[i] != 0; i++) if (avctx->sample_rate == avctx->codec->supported_samplerates[i]) @@ -776,6 +808,15 @@ int attribute_align_arg avcodec_open2(AVCodecContext *avctx, AVCodec *codec, AVD goto free_and_end; } } + + if (av_codec_is_decoder(avctx->codec)) { + /* validate channel layout from the decoder */ + if (avctx->channel_layout && + av_get_channel_layout_nb_channels(avctx->channel_layout) != avctx->channels) { + av_log(avctx, AV_LOG_WARNING, "channel layout does not match number of channels\n"); + avctx->channel_layout = 0; + } + } end: entangled_thread_counter--; @@ -797,38 +838,330 @@ free_and_end: goto end; } -int attribute_align_arg avcodec_encode_audio(AVCodecContext *avctx, uint8_t *buf, int buf_size, - const short *samples) +int ff_alloc_packet(AVPacket *avpkt, int size) { - if(buf_size < FF_MIN_BUFFER_SIZE && 0){ - av_log(avctx, AV_LOG_ERROR, "buffer smaller than minimum size\n"); - return -1; + if (size > INT_MAX - FF_INPUT_BUFFER_PADDING_SIZE) + return AVERROR(EINVAL); + + if (avpkt->data) { + void *destruct = avpkt->destruct; + + if (avpkt->size < size) + return AVERROR(EINVAL); + + av_init_packet(avpkt); + avpkt->destruct = destruct; + avpkt->size = size; + return 0; + } else { + return av_new_packet(avpkt, size); + } +} + +/** + * Pad last frame with silence. + */ +static int pad_last_frame(AVCodecContext *s, AVFrame **dst, const AVFrame *src) +{ + AVFrame *frame = NULL; + uint8_t *buf = NULL; + int ret; + + if (!(frame = avcodec_alloc_frame())) + return AVERROR(ENOMEM); + *frame = *src; + + if ((ret = av_samples_get_buffer_size(&frame->linesize[0], s->channels, + s->frame_size, s->sample_fmt, 0)) < 0) + goto fail; + + if (!(buf = av_malloc(ret))) { + ret = AVERROR(ENOMEM); + goto fail; } - if((avctx->codec->capabilities & CODEC_CAP_DELAY) || samples){ - int ret = avctx->codec->encode(avctx, buf, buf_size, samples); + + frame->nb_samples = s->frame_size; + if ((ret = avcodec_fill_audio_frame(frame, s->channels, s->sample_fmt, + buf, ret, 0)) < 0) + goto fail; + if ((ret = av_samples_copy(frame->extended_data, src->extended_data, 0, 0, + src->nb_samples, s->channels, s->sample_fmt)) < 0) + goto fail; + if ((ret = av_samples_set_silence(frame->extended_data, src->nb_samples, + frame->nb_samples - src->nb_samples, + s->channels, s->sample_fmt)) < 0) + goto fail; + + *dst = frame; + + return 0; + +fail: + if (frame->extended_data != frame->data) + av_freep(&frame->extended_data); + av_freep(&buf); + av_freep(&frame); + return ret; +} + +int attribute_align_arg avcodec_encode_audio2(AVCodecContext *avctx, + AVPacket *avpkt, + const AVFrame *frame, + int *got_packet_ptr) +{ + AVFrame tmp; + AVFrame *padded_frame = NULL; + int ret; + int user_packet = !!avpkt->data; + + *got_packet_ptr = 0; + + if (!(avctx->codec->capabilities & CODEC_CAP_DELAY) && !frame) { + av_free_packet(avpkt); + av_init_packet(avpkt); + return 0; + } + + /* ensure that extended_data is properly set */ + if (frame && !frame->extended_data) { + if (av_sample_fmt_is_planar(avctx->sample_fmt) && + avctx->channels > AV_NUM_DATA_POINTERS) { + av_log(avctx, AV_LOG_ERROR, "Encoding to a planar sample format, " + "with more than %d channels, but extended_data is not set.\n", + AV_NUM_DATA_POINTERS); + return AVERROR(EINVAL); + } + av_log(avctx, AV_LOG_WARNING, "extended_data is not set.\n"); + + tmp = *frame; + tmp.extended_data = tmp.data; + frame = &tmp; + } + + /* check for valid frame size */ + if (frame) { + if (avctx->codec->capabilities & CODEC_CAP_SMALL_LAST_FRAME) { + if (frame->nb_samples > avctx->frame_size) + return AVERROR(EINVAL); + } else if (!(avctx->codec->capabilities & CODEC_CAP_VARIABLE_FRAME_SIZE)) { + if (frame->nb_samples < avctx->frame_size && + !avctx->internal->last_audio_frame) { + ret = pad_last_frame(avctx, &padded_frame, frame); + if (ret < 0) + return ret; + + frame = padded_frame; + avctx->internal->last_audio_frame = 1; + } + + if (frame->nb_samples != avctx->frame_size) + return AVERROR(EINVAL); + } + } + + ret = avctx->codec->encode2(avctx, avpkt, frame, got_packet_ptr); + if (!ret) { + if (*got_packet_ptr) { + if (!(avctx->codec->capabilities & CODEC_CAP_DELAY)) { + if (avpkt->pts == AV_NOPTS_VALUE) + avpkt->pts = frame->pts; + if (!avpkt->duration) + avpkt->duration = ff_samples_to_time_base(avctx, + frame->nb_samples); + } + avpkt->dts = avpkt->pts; + } else { + avpkt->size = 0; + } + + if (!user_packet && avpkt->size) { + uint8_t *new_data = av_realloc(avpkt->data, avpkt->size); + if (new_data) + avpkt->data = new_data; + } + avctx->frame_number++; + } + + if (ret < 0 || !*got_packet_ptr) { + av_free_packet(avpkt); + av_init_packet(avpkt); return ret; - }else - return 0; + } + + /* NOTE: if we add any audio encoders which output non-keyframe packets, + this needs to be moved to the encoders, but for now we can do it + here to simplify things */ + avpkt->flags |= AV_PKT_FLAG_KEY; + + if (padded_frame) { + av_freep(&padded_frame->data[0]); + if (padded_frame->extended_data != padded_frame->data) + av_freep(&padded_frame->extended_data); + av_freep(&padded_frame); + } + + return ret; +} + +#if FF_API_OLD_DECODE_AUDIO +int attribute_align_arg avcodec_encode_audio(AVCodecContext *avctx, + uint8_t *buf, int buf_size, + const short *samples) +{ + AVPacket pkt; + AVFrame frame0; + AVFrame *frame; + int ret, samples_size, got_packet; + + av_init_packet(&pkt); + pkt.data = buf; + pkt.size = buf_size; + + if (samples) { + frame = &frame0; + avcodec_get_frame_defaults(frame); + + if (avctx->frame_size) { + frame->nb_samples = avctx->frame_size; + } else { + /* if frame_size is not set, the number of samples must be + calculated from the buffer size */ + int64_t nb_samples; + if (!av_get_bits_per_sample(avctx->codec_id)) { + av_log(avctx, AV_LOG_ERROR, "avcodec_encode_audio() does not " + "support this codec\n"); + return AVERROR(EINVAL); + } + nb_samples = (int64_t)buf_size * 8 / + (av_get_bits_per_sample(avctx->codec_id) * + avctx->channels); + if (nb_samples >= INT_MAX) + return AVERROR(EINVAL); + frame->nb_samples = nb_samples; + } + + /* it is assumed that the samples buffer is large enough based on the + relevant parameters */ + samples_size = av_samples_get_buffer_size(NULL, avctx->channels, + frame->nb_samples, + avctx->sample_fmt, 1); + if ((ret = avcodec_fill_audio_frame(frame, avctx->channels, + avctx->sample_fmt, + (const uint8_t *) samples, + samples_size, 1))) + return ret; + + /* fabricate frame pts from sample count. + this is needed because the avcodec_encode_audio() API does not have + a way for the user to provide pts */ + frame->pts = ff_samples_to_time_base(avctx, + avctx->internal->sample_count); + avctx->internal->sample_count += frame->nb_samples; + } else { + frame = NULL; + } + + got_packet = 0; + ret = avcodec_encode_audio2(avctx, &pkt, frame, &got_packet); + if (!ret && got_packet && avctx->coded_frame) { + avctx->coded_frame->pts = pkt.pts; + avctx->coded_frame->key_frame = !!(pkt.flags & AV_PKT_FLAG_KEY); + } + /* free any side data since we cannot return it */ + if (pkt.side_data_elems > 0) { + int i; + for (i = 0; i < pkt.side_data_elems; i++) + av_free(pkt.side_data[i].data); + av_freep(&pkt.side_data); + pkt.side_data_elems = 0; + } + + if (frame && frame->extended_data != frame->data) + av_free(frame->extended_data); + + return ret ? ret : pkt.size; } +#endif +#if FF_API_OLD_ENCODE_VIDEO int attribute_align_arg avcodec_encode_video(AVCodecContext *avctx, uint8_t *buf, int buf_size, const AVFrame *pict) { + AVPacket pkt; + int ret, got_packet = 0; + if(buf_size < FF_MIN_BUFFER_SIZE){ av_log(avctx, AV_LOG_ERROR, "buffer smaller than minimum size\n"); return -1; } - if(av_image_check_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); - avctx->frame_number++; - emms_c(); //needed to avoid an emms_c() call before every return; - return ret; - }else + av_init_packet(&pkt); + pkt.data = buf; + pkt.size = buf_size; + + ret = avcodec_encode_video2(avctx, &pkt, pict, &got_packet); + if (!ret && got_packet && avctx->coded_frame) { + avctx->coded_frame->pts = pkt.pts; + avctx->coded_frame->key_frame = !!(pkt.flags & AV_PKT_FLAG_KEY); + } + + /* free any side data since we cannot return it */ + if (pkt.side_data_elems > 0) { + int i; + for (i = 0; i < pkt.side_data_elems; i++) + av_free(pkt.side_data[i].data); + av_freep(&pkt.side_data); + pkt.side_data_elems = 0; + } + + return ret ? ret : pkt.size; +} +#endif + +int attribute_align_arg avcodec_encode_video2(AVCodecContext *avctx, + AVPacket *avpkt, + const AVFrame *frame, + int *got_packet_ptr) +{ + int ret; + int user_packet = !!avpkt->data; + + *got_packet_ptr = 0; + + if (!(avctx->codec->capabilities & CODEC_CAP_DELAY) && !frame) { + av_free_packet(avpkt); + av_init_packet(avpkt); + avpkt->size = 0; return 0; + } + + if (av_image_check_size(avctx->width, avctx->height, 0, avctx)) + return AVERROR(EINVAL); + + av_assert0(avctx->codec->encode2); + + ret = avctx->codec->encode2(avctx, avpkt, frame, got_packet_ptr); + if (!ret) { + if (!*got_packet_ptr) + avpkt->size = 0; + else if (!(avctx->codec->capabilities & CODEC_CAP_DELAY)) + avpkt->pts = avpkt->dts = frame->pts; + + if (!user_packet && avpkt->size) { + uint8_t *new_data = av_realloc(avpkt->data, avpkt->size); + if (new_data) + avpkt->data = new_data; + } + + avctx->frame_number++; + } + + if (ret < 0 || !*got_packet_ptr) + av_free_packet(avpkt); + + emms_c(); + return ret; } int avcodec_encode_subtitle(AVCodecContext *avctx, uint8_t *buf, int buf_size, @@ -846,6 +1179,48 @@ int avcodec_encode_subtitle(AVCodecContext *avctx, uint8_t *buf, int buf_size, return ret; } +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) @@ -857,6 +1232,7 @@ int attribute_align_arg avcodec_decode_video2(AVCodecContext *avctx, AVFrame *pi return -1; avctx->pkt = avpkt; + apply_param_change(avctx, avpkt); if((avctx->codec->capabilities & CODEC_CAP_DELAY) || avpkt->size || (avctx->active_thread_type&FF_THREAD_FRAME)){ if (HAVE_THREADS && avctx->active_thread_type&FF_THREAD_FRAME) @@ -866,6 +1242,10 @@ int attribute_align_arg avcodec_decode_video2(AVCodecContext *avctx, AVFrame *pi ret = avctx->codec->decode(avctx, picture, got_picture_ptr, avpkt); picture->pkt_dts= avpkt->dts; + picture->sample_aspect_ratio = avctx->sample_aspect_ratio; + picture->width = avctx->width; + picture->height = avctx->height; + picture->format = avctx->pix_fmt; } emms_c(); //needed to avoid an emms_c() call before every return; @@ -887,9 +1267,11 @@ 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 " - "avcodec_decode_audio3()\n"); - return AVERROR(EINVAL); + av_log(avctx, AV_LOG_ERROR, "Custom get_buffer() for use with" + "avcodec_decode_audio3() detected. Overriding with avcodec_default_get_buffer\n"); + av_log(avctx, AV_LOG_ERROR, "Please port your application to " + "avcodec_decode_audio4()\n"); + avctx->get_buffer = avcodec_default_get_buffer; } ret = avcodec_decode_audio4(avctx, &frame, &got_frame, avpkt); @@ -939,11 +1321,15 @@ int attribute_align_arg avcodec_decode_audio4(AVCodecContext *avctx, return AVERROR(EINVAL); } + apply_param_change(avctx, avpkt); + if ((avctx->codec->capabilities & CODEC_CAP_DELAY) || avpkt->size) { 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; @@ -998,18 +1384,21 @@ av_cold int avcodec_close(AVCodecContext *avctx) return -1; } - if (HAVE_THREADS && avctx->thread_opaque) - ff_thread_free(avctx); - if (avctx->codec && avctx->codec->close) - avctx->codec->close(avctx); - avcodec_default_free_buffers(avctx); - avctx->coded_frame = NULL; - av_freep(&avctx->internal); - if (avctx->codec && avctx->codec->priv_class) + if (avcodec_is_open(avctx)) { + if (HAVE_THREADS && avctx->thread_opaque) + ff_thread_free(avctx); + if (avctx->codec && avctx->codec->close) + avctx->codec->close(avctx); + avcodec_default_free_buffers(avctx); + avctx->coded_frame = NULL; + av_freep(&avctx->internal); + } + + if (avctx->priv_data && avctx->codec && avctx->codec->priv_class) av_opt_free(avctx->priv_data); av_opt_free(avctx); av_freep(&avctx->priv_data); - if(avctx->codec && avctx->codec->encode) + if (av_codec_is_encoder(avctx->codec)) av_freep(&avctx->extradata); avctx->codec = NULL; avctx->active_thread_type = 0; @@ -1022,12 +1411,12 @@ av_cold int avcodec_close(AVCodecContext *avctx) return 0; } -AVCodec *avcodec_find_encoder(enum CodecID id) +AVCodec *avcodec_find_encoder(enum AVCodecID id) { AVCodec *p, *experimental=NULL; p = first_avcodec; while (p) { - if (p->encode != NULL && p->id == id) { + if (av_codec_is_encoder(p) && p->id == id) { if (p->capabilities & CODEC_CAP_EXPERIMENTAL && !experimental) { experimental = p; } else @@ -1045,19 +1434,19 @@ AVCodec *avcodec_find_encoder_by_name(const char *name) return NULL; p = first_avcodec; while (p) { - if (p->encode != NULL && strcmp(name,p->name) == 0) + if (av_codec_is_encoder(p) && strcmp(name,p->name) == 0) return p; p = p->next; } return NULL; } -AVCodec *avcodec_find_decoder(enum CodecID id) +AVCodec *avcodec_find_decoder(enum AVCodecID id) { AVCodec *p; p = first_avcodec; while (p) { - if (p->decode != NULL && p->id == id) + if (av_codec_is_decoder(p) && p->id == id) return p; p = p->next; } @@ -1071,7 +1460,7 @@ AVCodec *avcodec_find_decoder_by_name(const char *name) return NULL; p = first_avcodec; while (p) { - if (p->decode != NULL && strcmp(name,p->name) == 0) + if (av_codec_is_decoder(p) && strcmp(name,p->name) == 0) return p; p = p->next; } @@ -1120,12 +1509,14 @@ void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode) { const char *codec_name; const char *profile = NULL; - AVCodec *p; + const AVCodec *p; char buf1[32]; int bitrate; AVRational display_aspect_ratio; - if (encode) + if (enc->codec) + p = enc->codec; + else if (encode) p = avcodec_find_encoder(enc->codec_id); else p = avcodec_find_decoder(enc->codec_id); @@ -1133,7 +1524,7 @@ void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode) if (p) { codec_name = p->name; profile = av_get_profile_name(p, enc->profile); - } else if (enc->codec_id == CODEC_ID_MPEG2TS) { + } else if (enc->codec_id == AV_CODEC_ID_MPEG2TS) { /* fake mpeg2 transport stream codec (currently not registered) */ codec_name = "mpeg2ts"; @@ -1323,65 +1714,213 @@ void avcodec_default_free_buffers(AVCodecContext *avctx) } } -#if FF_API_OLD_FF_PICT_TYPES -char av_get_pict_type_char(int pict_type){ - return av_get_picture_type_char(pict_type); -} -#endif - -int av_get_bits_per_sample(enum CodecID codec_id){ +int av_get_exact_bits_per_sample(enum AVCodecID codec_id) +{ switch(codec_id){ - case CODEC_ID_ADPCM_SBPRO_2: - return 2; - case CODEC_ID_ADPCM_SBPRO_3: - return 3; - case CODEC_ID_ADPCM_SBPRO_4: - case CODEC_ID_ADPCM_CT: - case CODEC_ID_ADPCM_IMA_WAV: - case CODEC_ID_ADPCM_IMA_QT: - case CODEC_ID_ADPCM_SWF: - case CODEC_ID_ADPCM_MS: - case CODEC_ID_ADPCM_YAMAHA: + case AV_CODEC_ID_ADPCM_CT: + case AV_CODEC_ID_ADPCM_IMA_APC: + case AV_CODEC_ID_ADPCM_IMA_EA_SEAD: + case AV_CODEC_ID_ADPCM_IMA_WS: + case AV_CODEC_ID_ADPCM_G722: + case AV_CODEC_ID_ADPCM_YAMAHA: return 4; - case CODEC_ID_ADPCM_G722: - case CODEC_ID_PCM_ALAW: - case CODEC_ID_PCM_MULAW: - case CODEC_ID_PCM_S8: - case CODEC_ID_PCM_U8: - case CODEC_ID_PCM_ZORK: + case AV_CODEC_ID_PCM_ALAW: + case AV_CODEC_ID_PCM_MULAW: + case AV_CODEC_ID_PCM_S8: + case AV_CODEC_ID_PCM_U8: + case AV_CODEC_ID_PCM_ZORK: return 8; - case CODEC_ID_PCM_S16BE: - case CODEC_ID_PCM_S16LE: - case CODEC_ID_PCM_S16LE_PLANAR: - case CODEC_ID_PCM_U16BE: - case CODEC_ID_PCM_U16LE: + case AV_CODEC_ID_PCM_S16BE: + case AV_CODEC_ID_PCM_S16LE: + case AV_CODEC_ID_PCM_S16LE_PLANAR: + case AV_CODEC_ID_PCM_U16BE: + case AV_CODEC_ID_PCM_U16LE: return 16; - case CODEC_ID_PCM_S24DAUD: - case CODEC_ID_PCM_S24BE: - case CODEC_ID_PCM_S24LE: - case CODEC_ID_PCM_U24BE: - case CODEC_ID_PCM_U24LE: + case AV_CODEC_ID_PCM_S24DAUD: + case AV_CODEC_ID_PCM_S24BE: + case AV_CODEC_ID_PCM_S24LE: + case AV_CODEC_ID_PCM_U24BE: + case AV_CODEC_ID_PCM_U24LE: return 24; - case CODEC_ID_PCM_S32BE: - case CODEC_ID_PCM_S32LE: - case CODEC_ID_PCM_U32BE: - case CODEC_ID_PCM_U32LE: - case CODEC_ID_PCM_F32BE: - case CODEC_ID_PCM_F32LE: + case AV_CODEC_ID_PCM_S32BE: + case AV_CODEC_ID_PCM_S32LE: + case AV_CODEC_ID_PCM_U32BE: + case AV_CODEC_ID_PCM_U32LE: + case AV_CODEC_ID_PCM_F32BE: + case AV_CODEC_ID_PCM_F32LE: return 32; - case CODEC_ID_PCM_F64BE: - case CODEC_ID_PCM_F64LE: + case AV_CODEC_ID_PCM_F64BE: + case AV_CODEC_ID_PCM_F64LE: return 64; default: return 0; } } -#if FF_API_OLD_SAMPLE_FMT -int av_get_bits_per_sample_format(enum AVSampleFormat sample_fmt) { - return av_get_bytes_per_sample(sample_fmt) << 3; +int av_get_bits_per_sample(enum AVCodecID codec_id) +{ + switch (codec_id) { + case AV_CODEC_ID_ADPCM_SBPRO_2: + return 2; + case AV_CODEC_ID_ADPCM_SBPRO_3: + return 3; + case AV_CODEC_ID_ADPCM_SBPRO_4: + case AV_CODEC_ID_ADPCM_IMA_WAV: + case AV_CODEC_ID_ADPCM_IMA_QT: + case AV_CODEC_ID_ADPCM_SWF: + case AV_CODEC_ID_ADPCM_MS: + return 4; + default: + return av_get_exact_bits_per_sample(codec_id); + } +} + +int av_get_audio_frame_duration(AVCodecContext *avctx, int frame_bytes) +{ + int id, sr, ch, ba, tag, bps; + + id = avctx->codec_id; + sr = avctx->sample_rate; + ch = avctx->channels; + ba = avctx->block_align; + tag = avctx->codec_tag; + bps = av_get_exact_bits_per_sample(avctx->codec_id); + + /* codecs with an exact constant bits per sample */ + if (bps > 0 && ch > 0 && frame_bytes > 0) + return (frame_bytes * 8) / (bps * ch); + bps = avctx->bits_per_coded_sample; + + /* codecs with a fixed packet duration */ + switch (id) { + case AV_CODEC_ID_ADPCM_ADX: return 32; + case AV_CODEC_ID_ADPCM_IMA_QT: return 64; + case AV_CODEC_ID_ADPCM_EA_XAS: return 128; + case AV_CODEC_ID_AMR_NB: + case AV_CODEC_ID_GSM: + case AV_CODEC_ID_QCELP: + case AV_CODEC_ID_RA_144: + case AV_CODEC_ID_RA_288: return 160; + case AV_CODEC_ID_IMC: return 256; + case AV_CODEC_ID_AMR_WB: + case AV_CODEC_ID_GSM_MS: return 320; + case AV_CODEC_ID_MP1: return 384; + case AV_CODEC_ID_ATRAC1: return 512; + case AV_CODEC_ID_ATRAC3: return 1024; + case AV_CODEC_ID_MP2: + case AV_CODEC_ID_MUSEPACK7: return 1152; + case AV_CODEC_ID_AC3: return 1536; + } + + if (sr > 0) { + /* calc from sample rate */ + if (id == AV_CODEC_ID_TTA) + return 256 * sr / 245; + + if (ch > 0) { + /* calc from sample rate and channels */ + if (id == AV_CODEC_ID_BINKAUDIO_DCT) + return (480 << (sr / 22050)) / ch; + } + } + + if (ba > 0) { + /* calc from block_align */ + if (id == AV_CODEC_ID_SIPR) { + switch (ba) { + case 20: return 160; + case 19: return 144; + case 29: return 288; + case 37: return 480; + } + } else if (id == AV_CODEC_ID_ILBC) { + switch (ba) { + case 38: return 160; + case 50: return 240; + } + } + } + + if (frame_bytes > 0) { + /* calc from frame_bytes only */ + if (id == AV_CODEC_ID_TRUESPEECH) + return 240 * (frame_bytes / 32); + if (id == AV_CODEC_ID_NELLYMOSER) + return 256 * (frame_bytes / 64); + + if (bps > 0) { + /* calc from frame_bytes and bits_per_coded_sample */ + if (id == AV_CODEC_ID_ADPCM_G726) + return frame_bytes * 8 / bps; + } + + if (ch > 0) { + /* calc from frame_bytes and channels */ + switch (id) { + case AV_CODEC_ID_ADPCM_4XM: + case AV_CODEC_ID_ADPCM_IMA_ISS: + return (frame_bytes - 4 * ch) * 2 / ch; + case AV_CODEC_ID_ADPCM_IMA_SMJPEG: + return (frame_bytes - 4) * 2 / ch; + case AV_CODEC_ID_ADPCM_IMA_AMV: + return (frame_bytes - 8) * 2 / ch; + case AV_CODEC_ID_ADPCM_XA: + return (frame_bytes / 128) * 224 / ch; + case AV_CODEC_ID_INTERPLAY_DPCM: + return (frame_bytes - 6 - ch) / ch; + case AV_CODEC_ID_ROQ_DPCM: + return (frame_bytes - 8) / ch; + case AV_CODEC_ID_XAN_DPCM: + return (frame_bytes - 2 * ch) / ch; + case AV_CODEC_ID_MACE3: + return 3 * frame_bytes / ch; + case AV_CODEC_ID_MACE6: + return 6 * frame_bytes / ch; + case AV_CODEC_ID_PCM_LXF: + return 2 * (frame_bytes / (5 * ch)); + } + + if (tag) { + /* calc from frame_bytes, channels, and codec_tag */ + if (id == AV_CODEC_ID_SOL_DPCM) { + if (tag == 3) + return frame_bytes / ch; + else + return frame_bytes * 2 / ch; + } + } + + if (ba > 0) { + /* calc from frame_bytes, channels, and block_align */ + int blocks = frame_bytes / ba; + switch (avctx->codec_id) { + case AV_CODEC_ID_ADPCM_IMA_WAV: + return blocks * (1 + (ba - 4 * ch) / (4 * ch) * 8); + case AV_CODEC_ID_ADPCM_IMA_DK3: + return blocks * (((ba - 16) * 2 / 3 * 4) / ch); + case AV_CODEC_ID_ADPCM_IMA_DK4: + return blocks * (1 + (ba - 4 * ch) * 2 / ch); + case AV_CODEC_ID_ADPCM_MS: + return blocks * (2 + (ba - 7 * ch) * 2 / ch); + } + } + + if (bps > 0) { + /* calc from frame_bytes, channels, and bits_per_coded_sample */ + switch (avctx->codec_id) { + case AV_CODEC_ID_PCM_DVD: + return 2 * (frame_bytes / ((bps * 2 / 8) * ch)); + case AV_CODEC_ID_PCM_BLURAY: + return frame_bytes / ((FFALIGN(ch, 2) * bps) / 8); + case AV_CODEC_ID_S302M: + return 2 * (frame_bytes / ((bps + 4) / 4)) / ch; + } + } + } + } + + return 0; } -#endif #if !HAVE_THREADS int ff_thread_init(AVCodecContext *s){ @@ -1450,7 +1989,7 @@ AVHWAccel *av_hwaccel_next(AVHWAccel *hwaccel) return hwaccel ? hwaccel->next : first_hwaccel; } -AVHWAccel *ff_find_hwaccel(enum CodecID codec_id, enum PixelFormat pix_fmt) +AVHWAccel *ff_find_hwaccel(enum AVCodecID codec_id, enum PixelFormat pix_fmt) { AVHWAccel *hwaccel=NULL; @@ -1535,24 +2074,21 @@ void ff_thread_await_progress(AVFrame *f, int progress, int field) #endif -#if FF_API_THREAD_INIT -int avcodec_thread_init(AVCodecContext *s, int thread_count) +enum AVMediaType avcodec_get_type(enum AVCodecID codec_id) { - s->thread_count = thread_count; - return ff_thread_init(s); -} -#endif - -enum AVMediaType avcodec_get_type(enum CodecID codec_id) -{ - if (codec_id <= CODEC_ID_NONE) + if (codec_id <= AV_CODEC_ID_NONE) return AVMEDIA_TYPE_UNKNOWN; - else if (codec_id < CODEC_ID_FIRST_AUDIO) + else if (codec_id < AV_CODEC_ID_FIRST_AUDIO) return AVMEDIA_TYPE_VIDEO; - else if (codec_id < CODEC_ID_FIRST_SUBTITLE) + else if (codec_id < AV_CODEC_ID_FIRST_SUBTITLE) return AVMEDIA_TYPE_AUDIO; - else if (codec_id < CODEC_ID_FIRST_UNKNOWN) + else if (codec_id < AV_CODEC_ID_FIRST_UNKNOWN) return AVMEDIA_TYPE_SUBTITLE; return AVMEDIA_TYPE_UNKNOWN; } + +int avcodec_is_open(AVCodecContext *s) +{ + return !!s->internal; +}