mirror of
https://github.com/obsproject/obs-studio.git
synced 2024-07-14 23:34:08 +00:00
deps/media-playback: New AVPacket pattern
FFmpeg has deprecated stack-allocated AVPacket objects, so make a pool and use the new pattern instead.
This commit is contained in:
parent
372b54ca7a
commit
d528f6cafa
70
deps/media-playback/media-playback/decode.c
vendored
70
deps/media-playback/media-playback/decode.c
vendored
|
@ -195,17 +195,19 @@ bool mp_decode_init(mp_media_t *m, enum AVMediaType type, bool hw)
|
|||
return true;
|
||||
}
|
||||
|
||||
extern void mp_media_free_packet(mp_media_t *m, AVPacket *pkt);
|
||||
|
||||
void mp_decode_clear_packets(struct mp_decode *d)
|
||||
{
|
||||
if (d->packet_pending) {
|
||||
av_packet_unref(&d->orig_pkt);
|
||||
d->packet_pending = false;
|
||||
if (d->pkt) {
|
||||
mp_media_free_packet(d->m, d->pkt);
|
||||
d->pkt = NULL;
|
||||
}
|
||||
|
||||
while (d->packets.size) {
|
||||
AVPacket pkt;
|
||||
AVPacket *pkt;
|
||||
circlebuf_pop_front(&d->packets, &pkt, sizeof(pkt));
|
||||
av_packet_unref(&pkt);
|
||||
mp_media_free_packet(d->m, pkt);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -241,7 +243,7 @@ void mp_decode_free(struct mp_decode *d)
|
|||
|
||||
void mp_decode_push_packet(struct mp_decode *decode, AVPacket *packet)
|
||||
{
|
||||
circlebuf_push_back(&decode->packets, packet, sizeof(*packet));
|
||||
circlebuf_push_back(&decode->packets, &packet, sizeof(packet));
|
||||
}
|
||||
|
||||
static inline int64_t get_estimated_duration(struct mp_decode *d,
|
||||
|
@ -269,7 +271,6 @@ static int decode_packet(struct mp_decode *d, int *got_frame)
|
|||
int ret;
|
||||
*got_frame = 0;
|
||||
|
||||
#ifdef USE_NEW_FFMPEG_DECODE_API
|
||||
ret = avcodec_receive_frame(d->decoder, d->in_frame);
|
||||
if (ret != 0 && ret != AVERROR(EAGAIN)) {
|
||||
if (ret == AVERROR_EOF)
|
||||
|
@ -278,7 +279,10 @@ static int decode_packet(struct mp_decode *d, int *got_frame)
|
|||
}
|
||||
|
||||
if (ret != 0) {
|
||||
ret = avcodec_send_packet(d->decoder, &d->pkt);
|
||||
if (!d->pkt)
|
||||
return 0;
|
||||
|
||||
ret = avcodec_send_packet(d->decoder, d->pkt);
|
||||
if (ret != 0 && ret != AVERROR(EAGAIN)) {
|
||||
if (ret == AVERROR_EOF)
|
||||
ret = 0;
|
||||
|
@ -293,22 +297,12 @@ static int decode_packet(struct mp_decode *d, int *got_frame)
|
|||
}
|
||||
|
||||
*got_frame = (ret == 0);
|
||||
ret = d->pkt.size;
|
||||
ret = d->pkt->size;
|
||||
} else {
|
||||
ret = 0;
|
||||
*got_frame = 1;
|
||||
}
|
||||
|
||||
#else
|
||||
if (d->audio) {
|
||||
ret = avcodec_decode_audio4(d->decoder, d->in_frame, got_frame,
|
||||
&d->pkt);
|
||||
} else {
|
||||
ret = avcodec_decode_video2(d->decoder, d->in_frame, got_frame,
|
||||
&d->pkt);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_NEW_HARDWARE_CODEC_METHOD
|
||||
if (*got_frame && d->hw) {
|
||||
if (d->hw_frame->format != d->hw_format) {
|
||||
|
@ -340,19 +334,13 @@ bool mp_decode_next(struct mp_decode *d)
|
|||
return true;
|
||||
|
||||
while (!d->frame_ready) {
|
||||
if (!d->packet_pending) {
|
||||
if (!d->pkt) {
|
||||
if (!d->packets.size) {
|
||||
if (eof) {
|
||||
d->pkt.data = NULL;
|
||||
d->pkt.size = 0;
|
||||
} else {
|
||||
if (!eof)
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
circlebuf_pop_front(&d->packets, &d->orig_pkt,
|
||||
sizeof(d->orig_pkt));
|
||||
d->pkt = d->orig_pkt;
|
||||
d->packet_pending = true;
|
||||
circlebuf_pop_front(&d->packets, &d->pkt,
|
||||
sizeof(d->pkt));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -368,28 +356,24 @@ bool mp_decode_next(struct mp_decode *d)
|
|||
av_err2str(ret));
|
||||
#endif
|
||||
|
||||
if (d->packet_pending) {
|
||||
av_packet_unref(&d->orig_pkt);
|
||||
av_init_packet(&d->orig_pkt);
|
||||
av_init_packet(&d->pkt);
|
||||
d->packet_pending = false;
|
||||
if (d->pkt) {
|
||||
mp_media_free_packet(d->m, d->pkt);
|
||||
d->pkt = NULL;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
d->frame_ready = !!got_frame;
|
||||
|
||||
if (d->packet_pending) {
|
||||
if (d->pkt.size) {
|
||||
d->pkt.data += ret;
|
||||
d->pkt.size -= ret;
|
||||
if (d->pkt) {
|
||||
if (d->pkt->size) {
|
||||
d->pkt->data += ret;
|
||||
d->pkt->size -= ret;
|
||||
}
|
||||
|
||||
if (d->pkt.size <= 0) {
|
||||
av_packet_unref(&d->orig_pkt);
|
||||
av_init_packet(&d->orig_pkt);
|
||||
av_init_packet(&d->pkt);
|
||||
d->packet_pending = false;
|
||||
if (d->pkt->size <= 0) {
|
||||
mp_media_free_packet(d->m, d->pkt);
|
||||
d->pkt = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
4
deps/media-playback/media-playback/decode.h
vendored
4
deps/media-playback/media-playback/decode.h
vendored
|
@ -68,9 +68,7 @@ struct mp_decode {
|
|||
bool eof;
|
||||
bool hw;
|
||||
|
||||
AVPacket orig_pkt;
|
||||
AVPacket pkt;
|
||||
bool packet_pending;
|
||||
AVPacket *pkt;
|
||||
struct circlebuf packets;
|
||||
};
|
||||
|
||||
|
|
38
deps/media-playback/media-playback/media.c
vendored
38
deps/media-playback/media-playback/media.c
vendored
|
@ -132,7 +132,7 @@ static inline enum video_range_type convert_color_range(enum AVColorRange r)
|
|||
}
|
||||
|
||||
static inline struct mp_decode *get_packet_decoder(mp_media_t *media,
|
||||
AVPacket *pkt)
|
||||
const AVPacket *pkt)
|
||||
{
|
||||
if (media->has_audio && pkt->stream_index == media->a.stream->index)
|
||||
return &media->a;
|
||||
|
@ -142,14 +142,24 @@ static inline struct mp_decode *get_packet_decoder(mp_media_t *media,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
void mp_media_free_packet(struct mp_media *media, AVPacket *pkt)
|
||||
{
|
||||
av_packet_unref(pkt);
|
||||
da_push_back(media->packet_pool, &pkt);
|
||||
}
|
||||
|
||||
static int mp_media_next_packet(mp_media_t *media)
|
||||
{
|
||||
AVPacket new_pkt;
|
||||
AVPacket pkt;
|
||||
av_init_packet(&pkt);
|
||||
new_pkt = pkt;
|
||||
AVPacket *pkt;
|
||||
AVPacket **const cached = da_end(media->packet_pool);
|
||||
if (cached) {
|
||||
pkt = *cached;
|
||||
da_pop_back(media->packet_pool);
|
||||
} else {
|
||||
pkt = av_packet_alloc();
|
||||
}
|
||||
|
||||
int ret = av_read_frame(media->fmt, &pkt);
|
||||
int ret = av_read_frame(media->fmt, pkt);
|
||||
if (ret < 0) {
|
||||
if (ret != AVERROR_EOF && ret != AVERROR_EXIT)
|
||||
blog(LOG_WARNING, "MP: av_read_frame failed: %s (%d)",
|
||||
|
@ -157,13 +167,13 @@ static int mp_media_next_packet(mp_media_t *media)
|
|||
return ret;
|
||||
}
|
||||
|
||||
struct mp_decode *d = get_packet_decoder(media, &pkt);
|
||||
if (d && pkt.size) {
|
||||
av_packet_ref(&new_pkt, &pkt);
|
||||
mp_decode_push_packet(d, &new_pkt);
|
||||
struct mp_decode *d = get_packet_decoder(media, pkt);
|
||||
if (d && pkt->size) {
|
||||
mp_decode_push_packet(d, pkt);
|
||||
} else {
|
||||
mp_media_free_packet(media, pkt);
|
||||
}
|
||||
|
||||
av_packet_unref(&pkt);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -385,7 +395,7 @@ static void mp_media_next_video(mp_media_t *m, bool preload)
|
|||
}
|
||||
|
||||
if (flip)
|
||||
frame->data[0] -= frame->linesize[0] * (f->height - 1);
|
||||
frame->data[0] -= frame->linesize[0] * ((size_t)f->height - 1);
|
||||
|
||||
new_format = convert_pixel_format(m->scale_format);
|
||||
new_space = convert_color_space(f->colorspace, f->color_trc);
|
||||
|
@ -820,6 +830,7 @@ bool mp_media_init(mp_media_t *media, const struct mp_media_info *info)
|
|||
media->buffering = info->buffering;
|
||||
media->speed = info->speed;
|
||||
media->is_local_file = info->is_local_file;
|
||||
da_init(media->packet_pool);
|
||||
|
||||
if (!info->is_local_file || media->speed < 1 || media->speed > 200)
|
||||
media->speed = 100;
|
||||
|
@ -867,6 +878,9 @@ void mp_media_free(mp_media_t *media)
|
|||
mp_kill_thread(media);
|
||||
mp_decode_free(&media->v);
|
||||
mp_decode_free(&media->a);
|
||||
for (size_t i = 0; i < media->packet_pool.num; i++)
|
||||
av_packet_free(&media->packet_pool.array[i]);
|
||||
da_free(media->packet_pool);
|
||||
avformat_close_input(&media->fmt);
|
||||
pthread_mutex_destroy(&media->mutex);
|
||||
os_sem_destroy(media->sem);
|
||||
|
|
5
deps/media-playback/media-playback/media.h
vendored
5
deps/media-playback/media-playback/media.h
vendored
|
@ -62,6 +62,7 @@ struct mp_media {
|
|||
int scale_linesizes[4];
|
||||
uint8_t *scale_pic[4];
|
||||
|
||||
DARRAY(AVPacket *) packet_pool;
|
||||
struct mp_decode v;
|
||||
struct mp_decode a;
|
||||
bool is_local_file;
|
||||
|
@ -137,10 +138,6 @@ extern void mp_media_seek_to(mp_media_t *m, int64_t pos);
|
|||
|
||||
/* #define DETAILED_DEBUG_INFO */
|
||||
|
||||
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 48, 101)
|
||||
#define USE_NEW_FFMPEG_DECODE_API
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue