#include <limits.h>
#include <float.h>
+volatile int ff_avcodec_locked;
static int volatile entangled_thread_counter = 0;
static int (*ff_lockmgr_cb)(void **mutex, enum AVLockOp op);
static void *codec_mutex;
static int audio_get_buffer(AVCodecContext *avctx, AVFrame *frame)
{
AVCodecInternal *avci = avctx->internal;
- InternalBuffer *buf;
int buf_size, ret;
+ av_freep(&avci->audio_data);
buf_size = av_samples_get_buffer_size(NULL, avctx->channels,
frame->nb_samples, avctx->sample_fmt,
0);
if (buf_size < 0)
return AVERROR(EINVAL);
- /* allocate InternalBuffer if needed */
- if (!avci->buffer) {
- avci->buffer = av_mallocz(sizeof(InternalBuffer));
- if (!avci->buffer)
- return AVERROR(ENOMEM);
- }
- buf = avci->buffer;
-
- /* if there is a previously-used internal buffer, check its size and
- * channel count to see if we can reuse it */
- if (buf->extended_data) {
- /* if current buffer is too small, free it */
- if (buf->extended_data[0] && buf_size > buf->audio_data_size) {
- av_free(buf->extended_data[0]);
- if (buf->extended_data != buf->data)
- av_free(buf->extended_data);
- buf->extended_data = NULL;
- buf->data[0] = NULL;
- }
- /* if number of channels has changed, reset and/or free extended data
- * pointers but leave data buffer in buf->data[0] for reuse */
- if (buf->nb_channels != avctx->channels) {
- if (buf->extended_data != buf->data)
- av_free(buf->extended_data);
- buf->extended_data = NULL;
- }
- }
-
- /* 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 (!buf->data[0]) {
- if (!(buf->data[0] = av_mallocz(buf_size)))
- return AVERROR(ENOMEM);
- buf->audio_data_size = buf_size;
- }
- if ((ret = avcodec_fill_audio_frame(frame, avctx->channels,
- avctx->sample_fmt, buf->data[0],
- buf->audio_data_size, 0)) < 0)
- return ret;
+ frame->data[0] = av_mallocz(buf_size);
+ if (!frame->data[0])
+ return AVERROR(ENOMEM);
- 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));
+ ret = avcodec_fill_audio_frame(frame, avctx->channels, avctx->sample_fmt,
+ frame->data[0], buf_size, 0);
+ if (ret < 0) {
+ av_freep(&frame->data[0]);
+ return ret;
}
- frame->type = FF_BUFFER_TYPE_INTERNAL;
-
+ avci->audio_data = frame->data[0];
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);
buf->height = s->height;
buf->pix_fmt = s->pix_fmt;
}
- pic->type = FF_BUFFER_TYPE_INTERNAL;
for (i = 0; i < AV_NUM_DATA_POINTERS; i++) {
pic->base[i] = buf->base[i];
int avcodec_default_get_buffer(AVCodecContext *avctx, AVFrame *frame)
{
+ frame->type = FF_BUFFER_TYPE_INTERNAL;
switch (avctx->codec_type) {
case AVMEDIA_TYPE_VIDEO:
return video_get_buffer(avctx, frame);
frame->pkt_pts = s->pkt->pts;
frame->pkt_pos = s->pkt->pos;
frame->pkt_duration = s->pkt->duration;
+ frame->pkt_size = s->pkt->size;
} else {
frame->pkt_pts = AV_NOPTS_VALUE;
frame->pkt_pos = -1;
frame->pkt_duration = 0;
+ frame->pkt_size = -1;
}
frame->reordered_opaque = s->reordered_opaque;
frame->best_effort_timestamp = AV_NOPTS_VALUE;
frame->pkt_duration = 0;
frame->pkt_pos = -1;
+ frame->pkt_size = -1;
frame->key_frame = 1;
frame->sample_aspect_ratio = (AVRational) {0, 1 };
frame->format = -1; /* unknown */
MAKE_ACCESSORS(AVFrame, frame, int, sample_rate)
MAKE_ACCESSORS(AVFrame, frame, AVDictionary *, metadata)
MAKE_ACCESSORS(AVFrame, frame, int, decode_error_flags)
+MAKE_ACCESSORS(AVFrame, frame, int, pkt_size)
MAKE_ACCESSORS(AVCodecContext, codec, AVRational, pkt_timebase)
MAKE_ACCESSORS(AVCodecContext, codec, const AVCodecDescriptor *, codec_descriptor)
{
int ret = 0;
- entangled_thread_counter--;
- /* Release any user-supplied mutex. */
- if (ff_lockmgr_cb) {
- (*ff_lockmgr_cb)(&codec_mutex, AV_LOCK_RELEASE);
- }
+ ff_unlock_avcodec();
ret = avcodec_open2(avctx, codec, options);
- /* If there is a user-supplied mutex locking routine, call it. */
- if (ff_lockmgr_cb) {
- if ((*ff_lockmgr_cb)(&codec_mutex, AV_LOCK_OBTAIN))
- return -1;
- }
- entangled_thread_counter++;
+ ff_lock_avcodec(avctx);
return ret;
}
if (options)
av_dict_copy(&tmp, *options, 0);
- /* If there is a user-supplied mutex locking routine, call it. */
- if (ff_lockmgr_cb) {
- if ((ret = (*ff_lockmgr_cb)(&codec_mutex, AV_LOCK_OBTAIN)) < 0)
- return ret;
- }
-
- entangled_thread_counter++;
- if (entangled_thread_counter != 1) {
- av_log(avctx, AV_LOG_ERROR, "Insufficient thread locking around avcodec_open/close()\n");
- ret = AVERROR(EINVAL);
- goto end;
- }
+ ret = ff_lock_avcodec(avctx);
+ if (ret < 0)
+ return ret;
avctx->internal = av_mallocz(sizeof(AVCodecInternal));
if (!avctx->internal) {
av_log(avctx, AV_LOG_WARNING, "Warning: not compiled with thread support, using thread emulation\n");
if (HAVE_THREADS) {
- entangled_thread_counter--; //we will instanciate a few encoders thus kick the counter to prevent false detection of a problem
+ ff_unlock_avcodec(); //we will instanciate a few encoders thus kick the counter to prevent false detection of a problem
ret = ff_frame_thread_encoder_init(avctx, options ? *options : NULL);
- entangled_thread_counter++;
+ ff_lock_avcodec(avctx);
if (ret < 0)
goto free_and_end;
}
} else if (avctx->channel_layout) {
avctx->channels = av_get_channel_layout_nb_channels(avctx->channel_layout);
}
+ if(avctx->codec_type == AVMEDIA_TYPE_VIDEO &&
+ avctx->codec_id != AV_CODEC_ID_PNG // For mplayer
+ ) {
+ if (avctx->width <= 0 || avctx->height <= 0) {
+ av_log(avctx, AV_LOG_ERROR, "dimensions not set\n");
+ ret = AVERROR(EINVAL);
+ goto free_and_end;
+ }
+ }
}
avctx->pts_correction_num_faulty_pts =
}
}
end:
- entangled_thread_counter--;
-
- /* Release any user-supplied mutex. */
- if (ff_lockmgr_cb) {
- (*ff_lockmgr_cb)(&codec_mutex, AV_LOCK_RELEASE);
- }
+ ff_unlock_avcodec();
if (options) {
av_dict_free(options);
*options = tmp;
else {
ret = avctx->codec->decode(avctx, picture, got_picture_ptr,
&tmp);
- picture->pkt_dts = avpkt->dts;
+ 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 == AV_PIX_FMT_NONE) picture->format = avctx->pix_fmt;
+ /* get_buffer is supposed to set frame parameters */
+ if (!(avctx->codec->capabilities & CODEC_CAP_DR1)) {
+ 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 == AV_PIX_FMT_NONE) picture->format = avctx->pix_fmt;
+ }
}
add_metadata_from_side_data(avctx, picture);
{
int ret = 0;
- entangled_thread_counter--;
- /* Release any user-supplied mutex. */
- if (ff_lockmgr_cb) {
- (*ff_lockmgr_cb)(&codec_mutex, AV_LOCK_RELEASE);
- }
+ ff_unlock_avcodec();
ret = avcodec_close(avctx);
- /* If there is a user-supplied mutex locking routine, call it. */
- if (ff_lockmgr_cb) {
- if ((*ff_lockmgr_cb)(&codec_mutex, AV_LOCK_OBTAIN))
- return -1;
- }
- entangled_thread_counter++;
+ ff_lock_avcodec(NULL);
return ret;
}
av_cold int avcodec_close(AVCodecContext *avctx)
{
- /* If there is a user-supplied mutex locking routine, call it. */
- if (ff_lockmgr_cb) {
- if ((*ff_lockmgr_cb)(&codec_mutex, AV_LOCK_OBTAIN))
- return -1;
- }
-
- entangled_thread_counter++;
- if (entangled_thread_counter != 1) {
- av_log(avctx, AV_LOG_ERROR, "insufficient thread locking around avcodec_open/close()\n");
- entangled_thread_counter--;
- return -1;
- }
+ int ret = ff_lock_avcodec(avctx);
+ if (ret < 0)
+ return ret;
if (avcodec_is_open(avctx)) {
if (HAVE_THREADS && avctx->internal->frame_thread_encoder && avctx->thread_count > 1) {
- entangled_thread_counter --;
+ ff_unlock_avcodec();
ff_frame_thread_encoder_free(avctx);
- entangled_thread_counter ++;
+ ff_lock_avcodec(avctx);
}
if (HAVE_THREADS && avctx->thread_opaque)
ff_thread_free(avctx);
av_freep(&avctx->extradata);
avctx->codec = NULL;
avctx->active_thread_type = 0;
- entangled_thread_counter--;
- /* Release any user-supplied mutex. */
- if (ff_lockmgr_cb) {
- (*ff_lockmgr_cb)(&codec_mutex, AV_LOCK_RELEASE);
- }
+ ff_unlock_avcodec();
return 0;
}
//last major bump but will fill up again over time, please don't remove it
// case AV_CODEC_ID_UTVIDEO_DEPRECATED: return AV_CODEC_ID_UTVIDEO;
case AV_CODEC_ID_OPUS_DEPRECATED: return AV_CODEC_ID_OPUS;
+ case AV_CODEC_ID_TAK_DEPRECATED : return AV_CODEC_ID_TAK;
default : return id;
}
}
snprintf(buf + strlen(buf), buf_size - strlen(buf),
", %s",
av_get_pix_fmt_name(enc->pix_fmt));
+ if (enc->bits_per_raw_sample &&
+ enc->bits_per_raw_sample <= av_pix_fmt_desc_get(enc->pix_fmt)->comp[0].depth_minus1)
+ snprintf(buf + strlen(buf), buf_size - strlen(buf),
+ " (%d bpc)", enc->bits_per_raw_sample);
}
if (enc->width) {
snprintf(buf + strlen(buf), buf_size - strlen(buf),
static void audio_free_buffers(AVCodecContext *avctx)
{
AVCodecInternal *avci = avctx->internal;
- InternalBuffer *buf;
-
- if (!avci->buffer)
- return;
- buf = avci->buffer;
-
- if (buf->extended_data) {
- av_free(buf->extended_data[0]);
- if (buf->extended_data != buf->data)
- av_freep(&buf->extended_data);
- }
- av_freep(&avci->buffer);
+ av_freep(&avci->audio_data);
}
void avcodec_default_free_buffers(AVCodecContext *avctx)
return 0;
}
+int ff_lock_avcodec(AVCodecContext *log_ctx)
+{
+ if (ff_lockmgr_cb) {
+ if ((*ff_lockmgr_cb)(&codec_mutex, AV_LOCK_OBTAIN))
+ return -1;
+ }
+ entangled_thread_counter++;
+ if (entangled_thread_counter != 1) {
+ av_log(log_ctx, AV_LOG_ERROR, "Insufficient thread locking around avcodec_open/close()\n");
+ ff_avcodec_locked = 1;
+ ff_unlock_avcodec();
+ return AVERROR(EINVAL);
+ }
+ av_assert0(!ff_avcodec_locked);
+ ff_avcodec_locked = 1;
+ return 0;
+}
+
+int ff_unlock_avcodec(void)
+{
+ av_assert0(ff_avcodec_locked);
+ ff_avcodec_locked = 0;
+ entangled_thread_counter--;
+ if (ff_lockmgr_cb) {
+ if ((*ff_lockmgr_cb)(&codec_mutex, AV_LOCK_RELEASE))
+ return -1;
+ }
+ return 0;
+}
+
int avpriv_lock_avformat(void)
{
if (ff_lockmgr_cb) {