New upstream version 24.0.1+dfsg1
This commit is contained in:
parent
b14f9eae6d
commit
5a730d6ec3
842 changed files with 42245 additions and 33385 deletions
1
deps/media-playback/CMakeLists.txt
vendored
1
deps/media-playback/CMakeLists.txt
vendored
|
|
@ -9,6 +9,7 @@ include_directories(
|
|||
)
|
||||
|
||||
set(media-playback_HEADERS
|
||||
media-playback/closest-format.h
|
||||
media-playback/decode.h
|
||||
media-playback/media.h
|
||||
)
|
||||
|
|
|
|||
|
|
@ -61,6 +61,15 @@ static enum AVPixelFormat closest_format(enum AVPixelFormat fmt)
|
|||
case AV_PIX_FMT_YUV420P14LE:
|
||||
return AV_PIX_FMT_YUV420P;
|
||||
|
||||
case AV_PIX_FMT_YUVA420P:
|
||||
return AV_PIX_FMT_YUVA420P;
|
||||
|
||||
case AV_PIX_FMT_YUVA422P:
|
||||
return AV_PIX_FMT_YUVA422P;
|
||||
|
||||
case AV_PIX_FMT_YUVA444P:
|
||||
return AV_PIX_FMT_YUVA444P;
|
||||
|
||||
case AV_PIX_FMT_RGBA:
|
||||
case AV_PIX_FMT_BGRA:
|
||||
case AV_PIX_FMT_BGR0:
|
||||
|
|
|
|||
235
deps/media-playback/media-playback/decode.c
vendored
235
deps/media-playback/media-playback/decode.c
vendored
|
|
@ -17,29 +17,62 @@
|
|||
#include "decode.h"
|
||||
#include "media.h"
|
||||
|
||||
static AVCodec *find_hardware_decoder(enum AVCodecID id)
|
||||
{
|
||||
AVHWAccel *hwa = av_hwaccel_next(NULL);
|
||||
AVCodec *c = NULL;
|
||||
#if LIBAVCODEC_VERSION_INT > AV_VERSION_INT(58, 4, 100)
|
||||
#define USE_NEW_HARDWARE_CODEC_METHOD
|
||||
#endif
|
||||
|
||||
while (hwa) {
|
||||
if (hwa->id == id) {
|
||||
if (hwa->pix_fmt == AV_PIX_FMT_VDTOOL ||
|
||||
hwa->pix_fmt == AV_PIX_FMT_DXVA2_VLD ||
|
||||
hwa->pix_fmt == AV_PIX_FMT_VAAPI_VLD) {
|
||||
c = avcodec_find_decoder_by_name(hwa->name);
|
||||
if (c)
|
||||
break;
|
||||
}
|
||||
#ifdef USE_NEW_HARDWARE_CODEC_METHOD
|
||||
enum AVHWDeviceType hw_priority[] = {
|
||||
AV_HWDEVICE_TYPE_D3D11VA, AV_HWDEVICE_TYPE_DXVA2,
|
||||
AV_HWDEVICE_TYPE_VAAPI, AV_HWDEVICE_TYPE_VDPAU,
|
||||
AV_HWDEVICE_TYPE_QSV, AV_HWDEVICE_TYPE_NONE,
|
||||
};
|
||||
|
||||
static bool has_hw_type(AVCodec *c, enum AVHWDeviceType type,
|
||||
enum AVPixelFormat *hw_format)
|
||||
{
|
||||
for (int i = 0;; i++) {
|
||||
const AVCodecHWConfig *config = avcodec_get_hw_config(c, i);
|
||||
if (!config) {
|
||||
break;
|
||||
}
|
||||
|
||||
hwa = av_hwaccel_next(hwa);
|
||||
if (config->methods & AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX &&
|
||||
config->device_type == type) {
|
||||
*hw_format = config->pix_fmt;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return c;
|
||||
return false;
|
||||
}
|
||||
|
||||
static int mp_open_codec(struct mp_decode *d)
|
||||
static void init_hw_decoder(struct mp_decode *d, AVCodecContext *c)
|
||||
{
|
||||
enum AVHWDeviceType *priority = hw_priority;
|
||||
AVBufferRef *hw_ctx = NULL;
|
||||
|
||||
while (*priority != AV_HWDEVICE_TYPE_NONE) {
|
||||
if (has_hw_type(d->codec, *priority, &d->hw_format)) {
|
||||
int ret = av_hwdevice_ctx_create(&hw_ctx, *priority,
|
||||
NULL, NULL, 0);
|
||||
if (ret == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
priority++;
|
||||
}
|
||||
|
||||
if (hw_ctx) {
|
||||
c->hw_device_ctx = av_buffer_ref(hw_ctx);
|
||||
c->opaque = d;
|
||||
d->hw_ctx = hw_ctx;
|
||||
d->hw = true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static int mp_open_codec(struct mp_decode *d, bool hw)
|
||||
{
|
||||
AVCodecContext *c;
|
||||
int ret;
|
||||
|
|
@ -58,12 +91,17 @@ static int mp_open_codec(struct mp_decode *d)
|
|||
c = d->stream->codec;
|
||||
#endif
|
||||
|
||||
if (c->thread_count == 1 &&
|
||||
c->codec_id != AV_CODEC_ID_PNG &&
|
||||
d->hw = false;
|
||||
|
||||
#ifdef USE_NEW_HARDWARE_CODEC_METHOD
|
||||
if (hw)
|
||||
init_hw_decoder(d, c);
|
||||
#endif
|
||||
|
||||
if (c->thread_count == 1 && c->codec_id != AV_CODEC_ID_PNG &&
|
||||
c->codec_id != AV_CODEC_ID_TIFF &&
|
||||
c->codec_id != AV_CODEC_ID_JPEG2000 &&
|
||||
c->codec_id != AV_CODEC_ID_MPEG4 &&
|
||||
c->codec_id != AV_CODEC_ID_WEBP)
|
||||
c->codec_id != AV_CODEC_ID_MPEG4 && c->codec_id != AV_CODEC_ID_WEBP)
|
||||
c->thread_count = 0;
|
||||
|
||||
ret = avcodec_open2(c, d->codec, NULL);
|
||||
|
|
@ -103,45 +141,54 @@ bool mp_decode_init(mp_media_t *m, enum AVMediaType type, bool hw)
|
|||
id = stream->codec->codec_id;
|
||||
#endif
|
||||
|
||||
if (hw) {
|
||||
d->codec = find_hardware_decoder(id);
|
||||
if (d->codec) {
|
||||
ret = mp_open_codec(d);
|
||||
if (ret < 0)
|
||||
d->codec = NULL;
|
||||
if (id == AV_CODEC_ID_VP8 || id == AV_CODEC_ID_VP9) {
|
||||
AVDictionaryEntry *tag = NULL;
|
||||
tag = av_dict_get(stream->metadata, "alpha_mode", tag,
|
||||
AV_DICT_IGNORE_SUFFIX);
|
||||
|
||||
if (tag && strcmp(tag->value, "1") == 0) {
|
||||
char *codec = (id == AV_CODEC_ID_VP8) ? "libvpx"
|
||||
: "libvpx-vp9";
|
||||
d->codec = avcodec_find_decoder_by_name(codec);
|
||||
}
|
||||
}
|
||||
|
||||
if (!d->codec)
|
||||
d->codec = avcodec_find_decoder(id);
|
||||
|
||||
if (!d->codec) {
|
||||
if (id == AV_CODEC_ID_VP8)
|
||||
d->codec = avcodec_find_decoder_by_name("libvpx");
|
||||
else if (id == AV_CODEC_ID_VP9)
|
||||
d->codec = avcodec_find_decoder_by_name("libvpx-vp9");
|
||||
|
||||
if (!d->codec)
|
||||
d->codec = avcodec_find_decoder(id);
|
||||
if (!d->codec) {
|
||||
blog(LOG_WARNING, "MP: Failed to find %s codec",
|
||||
av_get_media_type_string(type));
|
||||
return false;
|
||||
}
|
||||
|
||||
ret = mp_open_codec(d);
|
||||
if (ret < 0) {
|
||||
blog(LOG_WARNING, "MP: Failed to open %s decoder: %s",
|
||||
av_get_media_type_string(type),
|
||||
av_err2str(ret));
|
||||
return false;
|
||||
}
|
||||
blog(LOG_WARNING, "MP: Failed to find %s codec",
|
||||
av_get_media_type_string(type));
|
||||
return false;
|
||||
}
|
||||
|
||||
d->frame = av_frame_alloc();
|
||||
if (!d->frame) {
|
||||
blog(LOG_WARNING, "MP: Failed to allocate %s frame",
|
||||
av_get_media_type_string(type));
|
||||
ret = mp_open_codec(d, hw);
|
||||
if (ret < 0) {
|
||||
blog(LOG_WARNING, "MP: Failed to open %s decoder: %s",
|
||||
av_get_media_type_string(type), av_err2str(ret));
|
||||
return false;
|
||||
}
|
||||
|
||||
d->sw_frame = av_frame_alloc();
|
||||
if (!d->sw_frame) {
|
||||
blog(LOG_WARNING, "MP: Failed to allocate %s frame",
|
||||
av_get_media_type_string(type));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (d->hw) {
|
||||
d->hw_frame = av_frame_alloc();
|
||||
if (!d->hw_frame) {
|
||||
blog(LOG_WARNING, "MP: Failed to allocate %s hw frame",
|
||||
av_get_media_type_string(type));
|
||||
return false;
|
||||
}
|
||||
|
||||
d->in_frame = d->hw_frame;
|
||||
} else {
|
||||
d->in_frame = d->sw_frame;
|
||||
}
|
||||
|
||||
if (d->codec->capabilities & CODEC_CAP_TRUNC)
|
||||
d->decoder->flags |= CODEC_FLAG_TRUNC;
|
||||
return true;
|
||||
|
|
@ -166,6 +213,10 @@ void mp_decode_free(struct mp_decode *d)
|
|||
mp_decode_clear_packets(d);
|
||||
circlebuf_free(&d->packets);
|
||||
|
||||
if (d->hw_frame) {
|
||||
av_frame_unref(d->hw_frame);
|
||||
av_free(d->hw_frame);
|
||||
}
|
||||
if (d->decoder) {
|
||||
#if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(57, 40, 101)
|
||||
avcodec_free_context(&d->decoder);
|
||||
|
|
@ -173,11 +224,17 @@ void mp_decode_free(struct mp_decode *d)
|
|||
avcodec_close(d->decoder);
|
||||
#endif
|
||||
}
|
||||
if (d->frame) {
|
||||
av_frame_unref(d->frame);
|
||||
av_free(d->frame);
|
||||
if (d->sw_frame) {
|
||||
av_frame_unref(d->sw_frame);
|
||||
av_free(d->sw_frame);
|
||||
}
|
||||
|
||||
#ifdef USE_NEW_HARDWARE_CODEC_METHOD
|
||||
if (d->hw_ctx) {
|
||||
av_buffer_unref(&d->hw_ctx);
|
||||
}
|
||||
#endif
|
||||
|
||||
memset(d, 0, sizeof(*d));
|
||||
}
|
||||
|
||||
|
|
@ -187,22 +244,22 @@ void mp_decode_push_packet(struct mp_decode *decode, AVPacket *packet)
|
|||
}
|
||||
|
||||
static inline int64_t get_estimated_duration(struct mp_decode *d,
|
||||
int64_t last_pts)
|
||||
int64_t last_pts)
|
||||
{
|
||||
if (last_pts)
|
||||
return d->frame_pts - last_pts;
|
||||
|
||||
if (d->audio) {
|
||||
return av_rescale_q(d->frame->nb_samples,
|
||||
(AVRational){1, d->frame->sample_rate},
|
||||
(AVRational){1, 1000000000});
|
||||
return av_rescale_q(d->in_frame->nb_samples,
|
||||
(AVRational){1, d->in_frame->sample_rate},
|
||||
(AVRational){1, 1000000000});
|
||||
} else {
|
||||
if (d->last_duration)
|
||||
return d->last_duration;
|
||||
|
||||
return av_rescale_q(d->decoder->time_base.num,
|
||||
d->decoder->time_base,
|
||||
(AVRational){1, 1000000000});
|
||||
d->decoder->time_base,
|
||||
(AVRational){1, 1000000000});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -212,7 +269,7 @@ static int decode_packet(struct mp_decode *d, int *got_frame)
|
|||
*got_frame = 0;
|
||||
|
||||
#ifdef USE_NEW_FFMPEG_DECODE_API
|
||||
ret = avcodec_receive_frame(d->decoder, d->frame);
|
||||
ret = avcodec_receive_frame(d->decoder, d->in_frame);
|
||||
if (ret != 0 && ret != AVERROR(EAGAIN)) {
|
||||
if (ret == AVERROR_EOF)
|
||||
ret = 0;
|
||||
|
|
@ -227,7 +284,7 @@ static int decode_packet(struct mp_decode *d, int *got_frame)
|
|||
return ret;
|
||||
}
|
||||
|
||||
ret = avcodec_receive_frame(d->decoder, d->frame);
|
||||
ret = avcodec_receive_frame(d->decoder, d->in_frame);
|
||||
if (ret != 0 && ret != AVERROR(EAGAIN)) {
|
||||
if (ret == AVERROR_EOF)
|
||||
ret = 0;
|
||||
|
|
@ -243,13 +300,30 @@ static int decode_packet(struct mp_decode *d, int *got_frame)
|
|||
|
||||
#else
|
||||
if (d->audio) {
|
||||
ret = avcodec_decode_audio4(d->decoder,
|
||||
d->frame, got_frame, &d->pkt);
|
||||
ret = avcodec_decode_audio4(d->decoder, d->in_frame, got_frame,
|
||||
&d->pkt);
|
||||
} else {
|
||||
ret = avcodec_decode_video2(d->decoder,
|
||||
d->frame, got_frame, &d->pkt);
|
||||
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) {
|
||||
d->frame = d->hw_frame;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int err = av_hwframe_transfer_data(d->sw_frame, d->hw_frame, 0);
|
||||
if (err != 0) {
|
||||
ret = 0;
|
||||
*got_frame = false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
d->frame = d->sw_frame;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -275,7 +349,7 @@ bool mp_decode_next(struct mp_decode *d)
|
|||
}
|
||||
} else {
|
||||
circlebuf_pop_front(&d->packets, &d->orig_pkt,
|
||||
sizeof(d->orig_pkt));
|
||||
sizeof(d->orig_pkt));
|
||||
d->pkt = d->orig_pkt;
|
||||
d->packet_pending = true;
|
||||
}
|
||||
|
|
@ -290,7 +364,7 @@ bool mp_decode_next(struct mp_decode *d)
|
|||
if (ret < 0) {
|
||||
#ifdef DETAILED_DEBUG_INFO
|
||||
blog(LOG_DEBUG, "MP: decode failed: %s",
|
||||
av_err2str(ret));
|
||||
av_err2str(ret));
|
||||
#endif
|
||||
|
||||
if (d->packet_pending) {
|
||||
|
|
@ -322,29 +396,28 @@ bool mp_decode_next(struct mp_decode *d)
|
|||
if (d->frame_ready) {
|
||||
int64_t last_pts = d->frame_pts;
|
||||
|
||||
if (d->frame->best_effort_timestamp == AV_NOPTS_VALUE)
|
||||
if (d->in_frame->best_effort_timestamp == AV_NOPTS_VALUE)
|
||||
d->frame_pts = d->next_pts;
|
||||
else
|
||||
d->frame_pts = av_rescale_q(
|
||||
d->frame->best_effort_timestamp,
|
||||
d->stream->time_base,
|
||||
(AVRational){1, 1000000000});
|
||||
d->frame_pts =
|
||||
av_rescale_q(d->in_frame->best_effort_timestamp,
|
||||
d->stream->time_base,
|
||||
(AVRational){1, 1000000000});
|
||||
|
||||
int64_t duration = d->frame->pkt_duration;
|
||||
int64_t duration = d->in_frame->pkt_duration;
|
||||
if (!duration)
|
||||
duration = get_estimated_duration(d, last_pts);
|
||||
else
|
||||
duration = av_rescale_q(duration,
|
||||
d->stream->time_base,
|
||||
(AVRational){1, 1000000000});
|
||||
duration = av_rescale_q(duration, d->stream->time_base,
|
||||
(AVRational){1, 1000000000});
|
||||
|
||||
if (d->m->speed != 100) {
|
||||
d->frame_pts = av_rescale_q(d->frame_pts,
|
||||
(AVRational){1, d->m->speed},
|
||||
(AVRational){1, 100});
|
||||
d->frame_pts = av_rescale_q(
|
||||
d->frame_pts, (AVRational){1, d->m->speed},
|
||||
(AVRational){1, 100});
|
||||
duration = av_rescale_q(duration,
|
||||
(AVRational){1, d->m->speed},
|
||||
(AVRational){1, 100});
|
||||
(AVRational){1, d->m->speed},
|
||||
(AVRational){1, 100});
|
||||
}
|
||||
|
||||
d->last_duration = duration;
|
||||
|
|
|
|||
40
deps/media-playback/media-playback/decode.h
vendored
40
deps/media-playback/media-playback/decode.h
vendored
|
|
@ -53,29 +53,35 @@ extern "C" {
|
|||
struct mp_media;
|
||||
|
||||
struct mp_decode {
|
||||
struct mp_media *m;
|
||||
AVStream *stream;
|
||||
bool audio;
|
||||
struct mp_media *m;
|
||||
AVStream *stream;
|
||||
bool audio;
|
||||
|
||||
AVCodecContext *decoder;
|
||||
AVCodec *codec;
|
||||
AVCodecContext *decoder;
|
||||
AVBufferRef *hw_ctx;
|
||||
AVCodec *codec;
|
||||
|
||||
int64_t last_duration;
|
||||
int64_t frame_pts;
|
||||
int64_t next_pts;
|
||||
AVFrame *frame;
|
||||
bool got_first_keyframe;
|
||||
bool frame_ready;
|
||||
bool eof;
|
||||
int64_t last_duration;
|
||||
int64_t frame_pts;
|
||||
int64_t next_pts;
|
||||
AVFrame *in_frame;
|
||||
AVFrame *sw_frame;
|
||||
AVFrame *hw_frame;
|
||||
AVFrame *frame;
|
||||
enum AVPixelFormat hw_format;
|
||||
bool got_first_keyframe;
|
||||
bool frame_ready;
|
||||
bool eof;
|
||||
bool hw;
|
||||
|
||||
AVPacket orig_pkt;
|
||||
AVPacket pkt;
|
||||
bool packet_pending;
|
||||
struct circlebuf packets;
|
||||
AVPacket orig_pkt;
|
||||
AVPacket pkt;
|
||||
bool packet_pending;
|
||||
struct circlebuf packets;
|
||||
};
|
||||
|
||||
extern bool mp_decode_init(struct mp_media *media, enum AVMediaType type,
|
||||
bool hw);
|
||||
bool hw);
|
||||
extern void mp_decode_free(struct mp_decode *decode);
|
||||
|
||||
extern void mp_decode_clear_packets(struct mp_decode *decode);
|
||||
|
|
|
|||
174
deps/media-playback/media-playback/media.c
vendored
174
deps/media-playback/media-playback/media.c
vendored
|
|
@ -30,15 +30,30 @@ static int64_t base_sys_ts = 0;
|
|||
static inline enum video_format convert_pixel_format(int f)
|
||||
{
|
||||
switch (f) {
|
||||
case AV_PIX_FMT_NONE: return VIDEO_FORMAT_NONE;
|
||||
case AV_PIX_FMT_YUV420P: return VIDEO_FORMAT_I420;
|
||||
case AV_PIX_FMT_NV12: return VIDEO_FORMAT_NV12;
|
||||
case AV_PIX_FMT_YUYV422: return VIDEO_FORMAT_YUY2;
|
||||
case AV_PIX_FMT_YUV444P: return VIDEO_FORMAT_I444;
|
||||
case AV_PIX_FMT_UYVY422: return VIDEO_FORMAT_UYVY;
|
||||
case AV_PIX_FMT_RGBA: return VIDEO_FORMAT_RGBA;
|
||||
case AV_PIX_FMT_BGRA: return VIDEO_FORMAT_BGRA;
|
||||
case AV_PIX_FMT_BGR0: return VIDEO_FORMAT_BGRX;
|
||||
case AV_PIX_FMT_NONE:
|
||||
return VIDEO_FORMAT_NONE;
|
||||
case AV_PIX_FMT_YUV420P:
|
||||
return VIDEO_FORMAT_I420;
|
||||
case AV_PIX_FMT_NV12:
|
||||
return VIDEO_FORMAT_NV12;
|
||||
case AV_PIX_FMT_YUYV422:
|
||||
return VIDEO_FORMAT_YUY2;
|
||||
case AV_PIX_FMT_YUV444P:
|
||||
return VIDEO_FORMAT_I444;
|
||||
case AV_PIX_FMT_UYVY422:
|
||||
return VIDEO_FORMAT_UYVY;
|
||||
case AV_PIX_FMT_RGBA:
|
||||
return VIDEO_FORMAT_RGBA;
|
||||
case AV_PIX_FMT_BGRA:
|
||||
return VIDEO_FORMAT_BGRA;
|
||||
case AV_PIX_FMT_BGR0:
|
||||
return VIDEO_FORMAT_BGRX;
|
||||
case AV_PIX_FMT_YUVA420P:
|
||||
return VIDEO_FORMAT_I40A;
|
||||
case AV_PIX_FMT_YUVA422P:
|
||||
return VIDEO_FORMAT_I42A;
|
||||
case AV_PIX_FMT_YUVA444P:
|
||||
return VIDEO_FORMAT_YUVA;
|
||||
default:;
|
||||
}
|
||||
|
||||
|
|
@ -48,14 +63,22 @@ static inline enum video_format convert_pixel_format(int f)
|
|||
static inline enum audio_format convert_sample_format(int f)
|
||||
{
|
||||
switch (f) {
|
||||
case AV_SAMPLE_FMT_U8: return AUDIO_FORMAT_U8BIT;
|
||||
case AV_SAMPLE_FMT_S16: return AUDIO_FORMAT_16BIT;
|
||||
case AV_SAMPLE_FMT_S32: return AUDIO_FORMAT_32BIT;
|
||||
case AV_SAMPLE_FMT_FLT: return AUDIO_FORMAT_FLOAT;
|
||||
case AV_SAMPLE_FMT_U8P: return AUDIO_FORMAT_U8BIT_PLANAR;
|
||||
case AV_SAMPLE_FMT_S16P: return AUDIO_FORMAT_16BIT_PLANAR;
|
||||
case AV_SAMPLE_FMT_S32P: return AUDIO_FORMAT_32BIT_PLANAR;
|
||||
case AV_SAMPLE_FMT_FLTP: return AUDIO_FORMAT_FLOAT_PLANAR;
|
||||
case AV_SAMPLE_FMT_U8:
|
||||
return AUDIO_FORMAT_U8BIT;
|
||||
case AV_SAMPLE_FMT_S16:
|
||||
return AUDIO_FORMAT_16BIT;
|
||||
case AV_SAMPLE_FMT_S32:
|
||||
return AUDIO_FORMAT_32BIT;
|
||||
case AV_SAMPLE_FMT_FLT:
|
||||
return AUDIO_FORMAT_FLOAT;
|
||||
case AV_SAMPLE_FMT_U8P:
|
||||
return AUDIO_FORMAT_U8BIT_PLANAR;
|
||||
case AV_SAMPLE_FMT_S16P:
|
||||
return AUDIO_FORMAT_16BIT_PLANAR;
|
||||
case AV_SAMPLE_FMT_S32P:
|
||||
return AUDIO_FORMAT_32BIT_PLANAR;
|
||||
case AV_SAMPLE_FMT_FLTP:
|
||||
return AUDIO_FORMAT_FLOAT_PLANAR;
|
||||
default:;
|
||||
}
|
||||
|
||||
|
|
@ -65,15 +88,24 @@ static inline enum audio_format convert_sample_format(int f)
|
|||
static inline enum speaker_layout convert_speaker_layout(uint8_t channels)
|
||||
{
|
||||
switch (channels) {
|
||||
case 0: return SPEAKERS_UNKNOWN;
|
||||
case 1: return SPEAKERS_MONO;
|
||||
case 2: return SPEAKERS_STEREO;
|
||||
case 3: return SPEAKERS_2POINT1;
|
||||
case 4: return SPEAKERS_4POINT0;
|
||||
case 5: return SPEAKERS_4POINT1;
|
||||
case 6: return SPEAKERS_5POINT1;
|
||||
case 8: return SPEAKERS_7POINT1;
|
||||
default: return SPEAKERS_UNKNOWN;
|
||||
case 0:
|
||||
return SPEAKERS_UNKNOWN;
|
||||
case 1:
|
||||
return SPEAKERS_MONO;
|
||||
case 2:
|
||||
return SPEAKERS_STEREO;
|
||||
case 3:
|
||||
return SPEAKERS_2POINT1;
|
||||
case 4:
|
||||
return SPEAKERS_4POINT0;
|
||||
case 5:
|
||||
return SPEAKERS_4POINT1;
|
||||
case 6:
|
||||
return SPEAKERS_5POINT1;
|
||||
case 8:
|
||||
return SPEAKERS_7POINT1;
|
||||
default:
|
||||
return SPEAKERS_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -88,7 +120,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)
|
||||
AVPacket *pkt)
|
||||
{
|
||||
if (media->has_audio && pkt->stream_index == media->a.stream->index)
|
||||
return &media->a;
|
||||
|
|
@ -109,7 +141,7 @@ static int mp_media_next_packet(mp_media_t *media)
|
|||
if (ret < 0) {
|
||||
if (ret != AVERROR_EOF)
|
||||
blog(LOG_WARNING, "MP: av_read_frame failed: %s (%d)",
|
||||
av_err2str(ret), ret);
|
||||
av_err2str(ret), ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -160,7 +192,7 @@ static inline int get_sws_range(enum AVColorRange r)
|
|||
return r == AVCOL_RANGE_JPEG ? 1 : 0;
|
||||
}
|
||||
|
||||
#define FIXED_1_0 (1<<16)
|
||||
#define FIXED_1_0 (1 << 16)
|
||||
|
||||
static bool mp_media_init_scaling(mp_media_t *m)
|
||||
{
|
||||
|
|
@ -168,23 +200,23 @@ static bool mp_media_init_scaling(mp_media_t *m)
|
|||
int range = get_sws_range(m->v.decoder->color_range);
|
||||
const int *coeff = sws_getCoefficients(space);
|
||||
|
||||
m->swscale = sws_getCachedContext(NULL,
|
||||
m->v.decoder->width, m->v.decoder->height,
|
||||
m->v.decoder->pix_fmt,
|
||||
m->v.decoder->width, m->v.decoder->height,
|
||||
m->scale_format,
|
||||
SWS_FAST_BILINEAR, NULL, NULL, NULL);
|
||||
m->swscale = sws_getCachedContext(NULL, m->v.decoder->width,
|
||||
m->v.decoder->height,
|
||||
m->v.decoder->pix_fmt,
|
||||
m->v.decoder->width,
|
||||
m->v.decoder->height, m->scale_format,
|
||||
SWS_FAST_BILINEAR, NULL, NULL, NULL);
|
||||
if (!m->swscale) {
|
||||
blog(LOG_WARNING, "MP: Failed to initialize scaler");
|
||||
return false;
|
||||
}
|
||||
|
||||
sws_setColorspaceDetails(m->swscale, coeff, range, coeff, range, 0,
|
||||
FIXED_1_0, FIXED_1_0);
|
||||
FIXED_1_0, FIXED_1_0);
|
||||
|
||||
int ret = av_image_alloc(m->scale_pic, m->scale_linesizes,
|
||||
m->v.decoder->width, m->v.decoder->height,
|
||||
m->scale_format, 1);
|
||||
m->v.decoder->width, m->v.decoder->height,
|
||||
m->scale_format, 1);
|
||||
if (ret < 0) {
|
||||
blog(LOG_WARNING, "MP: Failed to create scale pic data");
|
||||
return false;
|
||||
|
|
@ -250,8 +282,7 @@ static inline int64_t mp_media_get_base_pts(mp_media_t *m)
|
|||
return base_ts;
|
||||
}
|
||||
|
||||
static inline bool mp_media_can_play_frame(mp_media_t *m,
|
||||
struct mp_decode *d)
|
||||
static inline bool mp_media_can_play_frame(mp_media_t *m, struct mp_decode *d)
|
||||
{
|
||||
return d->frame_ready && d->frame_pts <= m->next_pts_ns;
|
||||
}
|
||||
|
|
@ -277,7 +308,7 @@ static void mp_media_next_audio(mp_media_t *m)
|
|||
audio.format = convert_sample_format(f->format);
|
||||
audio.frames = f->nb_samples;
|
||||
audio.timestamp = m->base_ts + d->frame_pts - m->start_ts +
|
||||
m->play_sys_ts - base_sys_ts;
|
||||
m->play_sys_ts - base_sys_ts;
|
||||
|
||||
if (audio.format == AUDIO_FORMAT_UNKNOWN)
|
||||
return;
|
||||
|
|
@ -308,10 +339,9 @@ static void mp_media_next_video(mp_media_t *m, bool preload)
|
|||
|
||||
bool flip = false;
|
||||
if (m->swscale) {
|
||||
int ret = sws_scale(m->swscale,
|
||||
(const uint8_t *const *)f->data, f->linesize,
|
||||
0, f->height,
|
||||
m->scale_pic, m->scale_linesizes);
|
||||
int ret = sws_scale(m->swscale, (const uint8_t *const *)f->data,
|
||||
f->linesize, 0, f->height, m->scale_pic,
|
||||
m->scale_linesizes);
|
||||
if (ret < 0)
|
||||
return;
|
||||
|
||||
|
|
@ -334,25 +364,22 @@ static void mp_media_next_video(mp_media_t *m, bool preload)
|
|||
frame->data[0] -= frame->linesize[0] * (f->height - 1);
|
||||
|
||||
new_format = convert_pixel_format(m->scale_format);
|
||||
new_space = convert_color_space(f->colorspace);
|
||||
new_range = m->force_range == VIDEO_RANGE_DEFAULT
|
||||
? convert_color_range(f->color_range)
|
||||
: m->force_range;
|
||||
new_space = convert_color_space(f->colorspace);
|
||||
new_range = m->force_range == VIDEO_RANGE_DEFAULT
|
||||
? convert_color_range(f->color_range)
|
||||
: m->force_range;
|
||||
|
||||
if (new_format != frame->format ||
|
||||
new_space != m->cur_space ||
|
||||
new_range != m->cur_range) {
|
||||
if (new_format != frame->format || new_space != m->cur_space ||
|
||||
new_range != m->cur_range) {
|
||||
bool success;
|
||||
|
||||
frame->format = new_format;
|
||||
frame->full_range = new_range == VIDEO_RANGE_FULL;
|
||||
|
||||
success = video_format_get_parameters(
|
||||
new_space,
|
||||
new_range,
|
||||
frame->color_matrix,
|
||||
frame->color_range_min,
|
||||
frame->color_range_max);
|
||||
success = video_format_get_parameters(new_space, new_range,
|
||||
frame->color_matrix,
|
||||
frame->color_range_min,
|
||||
frame->color_range_max);
|
||||
|
||||
frame->format = new_format;
|
||||
m->cur_space = new_space;
|
||||
|
|
@ -368,7 +395,7 @@ static void mp_media_next_video(mp_media_t *m, bool preload)
|
|||
return;
|
||||
|
||||
frame->timestamp = m->base_ts + d->frame_pts - m->start_ts +
|
||||
m->play_sys_ts - base_sys_ts;
|
||||
m->play_sys_ts - base_sys_ts;
|
||||
frame->width = f->width;
|
||||
frame->height = f->height;
|
||||
frame->flip = flip;
|
||||
|
|
@ -420,14 +447,15 @@ static bool mp_media_reset(mp_media_t *m)
|
|||
}
|
||||
|
||||
int64_t seek_target = seek_flags == AVSEEK_FLAG_BACKWARD
|
||||
? av_rescale_q(seek_pos, AV_TIME_BASE_Q, stream->time_base)
|
||||
: seek_pos;
|
||||
? av_rescale_q(seek_pos, AV_TIME_BASE_Q,
|
||||
stream->time_base)
|
||||
: seek_pos;
|
||||
|
||||
if (m->is_local_file) {
|
||||
int ret = av_seek_frame(m->fmt, 0, seek_target, seek_flags);
|
||||
if (ret < 0) {
|
||||
blog(LOG_WARNING, "MP: Failed to seek: %s",
|
||||
av_err2str(ret));
|
||||
av_err2str(ret));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -538,8 +566,10 @@ static bool init_avformat(mp_media_t *m)
|
|||
if (m->format_name && *m->format_name) {
|
||||
format = av_find_input_format(m->format_name);
|
||||
if (!format)
|
||||
blog(LOG_INFO, "MP: Unable to find input format for "
|
||||
"'%s'", m->path);
|
||||
blog(LOG_INFO,
|
||||
"MP: Unable to find input format for "
|
||||
"'%s'",
|
||||
m->path);
|
||||
}
|
||||
|
||||
AVDictionary *opts = NULL;
|
||||
|
|
@ -551,7 +581,7 @@ static bool init_avformat(mp_media_t *m)
|
|||
m->fmt->interrupt_callback.opaque = m;
|
||||
|
||||
int ret = avformat_open_input(&m->fmt, m->path, format,
|
||||
opts ? &opts : NULL);
|
||||
opts ? &opts : NULL);
|
||||
av_dict_free(&opts);
|
||||
|
||||
if (ret < 0) {
|
||||
|
|
@ -561,7 +591,7 @@ static bool init_avformat(mp_media_t *m)
|
|||
|
||||
if (avformat_find_stream_info(m->fmt, NULL) < 0) {
|
||||
blog(LOG_WARNING, "MP: Failed to find stream info for '%s'",
|
||||
m->path);
|
||||
m->path);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -569,8 +599,10 @@ static bool init_avformat(mp_media_t *m)
|
|||
m->has_audio = mp_decode_init(m, AVMEDIA_TYPE_AUDIO, m->hw);
|
||||
|
||||
if (!m->has_video && !m->has_audio) {
|
||||
blog(LOG_WARNING, "MP: Could not initialize audio or video: "
|
||||
"'%s'", m->path);
|
||||
blog(LOG_WARNING,
|
||||
"MP: Could not initialize audio or video: "
|
||||
"'%s'",
|
||||
m->path);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -653,7 +685,7 @@ static void *mp_media_thread_start(void *opaque)
|
|||
}
|
||||
|
||||
static inline bool mp_media_init_internal(mp_media_t *m,
|
||||
const struct mp_media_info *info)
|
||||
const struct mp_media_info *info)
|
||||
{
|
||||
if (pthread_mutex_init(&m->mutex, NULL) != 0) {
|
||||
blog(LOG_WARNING, "MP: Failed to init mutex");
|
||||
|
|
@ -696,9 +728,11 @@ bool mp_media_init(mp_media_t *media, const struct mp_media_info *info)
|
|||
|
||||
static bool initialized = false;
|
||||
if (!initialized) {
|
||||
#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(58, 9, 100)
|
||||
av_register_all();
|
||||
avdevice_register_all();
|
||||
avcodec_register_all();
|
||||
#endif
|
||||
avdevice_register_all();
|
||||
avformat_network_init();
|
||||
initialized = true;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue