mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-05-18 00:12:46 +00:00
Merge branch 'ffdemux-no-typefinder' into 'main'
libav: Fix compatibility with ffmpeg 7 Closes #3378 See merge request gstreamer/gstreamer!6505
This commit is contained in:
commit
4e293b6547
|
@ -72,18 +72,6 @@ gst_ffmpeg_avcodec_open (AVCodecContext * avctx, const AVCodec * codec)
|
|||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
gst_ffmpeg_avcodec_close (AVCodecContext * avctx)
|
||||
{
|
||||
int ret;
|
||||
|
||||
g_mutex_lock (&gst_avcodec_mutex);
|
||||
ret = avcodec_close (avctx);
|
||||
g_mutex_unlock (&gst_avcodec_mutex);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
gst_ffmpeg_av_find_stream_info (AVFormatContext * ic)
|
||||
{
|
||||
|
|
|
@ -46,7 +46,6 @@ extern gboolean gst_ffmpegdeinterlace_register (GstPlugin * plugin);
|
|||
extern gboolean gst_ffmpegvidcmp_register (GstPlugin * plugin);
|
||||
|
||||
int gst_ffmpeg_avcodec_open (AVCodecContext *avctx, const AVCodec *codec);
|
||||
int gst_ffmpeg_avcodec_close (AVCodecContext *avctx);
|
||||
int gst_ffmpeg_av_find_stream_info(AVFormatContext *ic);
|
||||
|
||||
G_END_DECLS
|
||||
|
|
|
@ -145,16 +145,6 @@ gst_ffmpegauddec_class_init (GstFFMpegAudDecClass * klass)
|
|||
static void
|
||||
gst_ffmpegauddec_init (GstFFMpegAudDec * ffmpegdec)
|
||||
{
|
||||
GstFFMpegAudDecClass *klass =
|
||||
(GstFFMpegAudDecClass *) G_OBJECT_GET_CLASS (ffmpegdec);
|
||||
|
||||
/* some ffmpeg data */
|
||||
ffmpegdec->context = avcodec_alloc_context3 (klass->in_plugin);
|
||||
ffmpegdec->context->opaque = ffmpegdec;
|
||||
ffmpegdec->opened = FALSE;
|
||||
|
||||
ffmpegdec->frame = av_frame_alloc ();
|
||||
|
||||
GST_PAD_SET_ACCEPT_TEMPLATE (GST_AUDIO_DECODER_SINK_PAD (ffmpegdec));
|
||||
gst_audio_decoder_set_use_default_pad_acceptcaps (GST_AUDIO_DECODER_CAST
|
||||
(ffmpegdec), TRUE);
|
||||
|
@ -175,60 +165,24 @@ gst_ffmpegauddec_finalize (GObject * object)
|
|||
}
|
||||
|
||||
/* With LOCK */
|
||||
static gboolean
|
||||
gst_ffmpegauddec_close (GstFFMpegAudDec * ffmpegdec, gboolean reset)
|
||||
static void
|
||||
gst_ffmpegauddec_close (GstFFMpegAudDec * ffmpegdec)
|
||||
{
|
||||
GstFFMpegAudDecClass *oclass;
|
||||
|
||||
oclass = (GstFFMpegAudDecClass *) (G_OBJECT_GET_CLASS (ffmpegdec));
|
||||
|
||||
GST_LOG_OBJECT (ffmpegdec, "closing libav codec");
|
||||
|
||||
gst_caps_replace (&ffmpegdec->last_caps, NULL);
|
||||
|
||||
gst_ffmpeg_avcodec_close (ffmpegdec->context);
|
||||
ffmpegdec->opened = FALSE;
|
||||
|
||||
av_freep (&ffmpegdec->context->extradata);
|
||||
|
||||
if (reset) {
|
||||
avcodec_free_context (&ffmpegdec->context);
|
||||
ffmpegdec->context = avcodec_alloc_context3 (oclass->in_plugin);
|
||||
if (ffmpegdec->context == NULL) {
|
||||
GST_DEBUG_OBJECT (ffmpegdec, "Failed to set context defaults");
|
||||
return FALSE;
|
||||
}
|
||||
ffmpegdec->context->opaque = ffmpegdec;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
avcodec_free_context (&ffmpegdec->context);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_ffmpegauddec_start (GstAudioDecoder * decoder)
|
||||
{
|
||||
GstFFMpegAudDec *ffmpegdec = (GstFFMpegAudDec *) decoder;
|
||||
GstFFMpegAudDecClass *oclass;
|
||||
|
||||
oclass = (GstFFMpegAudDecClass *) (G_OBJECT_GET_CLASS (ffmpegdec));
|
||||
|
||||
GST_OBJECT_LOCK (ffmpegdec);
|
||||
ffmpegdec->frame = av_frame_alloc ();
|
||||
avcodec_free_context (&ffmpegdec->context);
|
||||
ffmpegdec->context = avcodec_alloc_context3 (oclass->in_plugin);
|
||||
if (ffmpegdec->context == NULL) {
|
||||
GST_DEBUG_OBJECT (ffmpegdec, "Failed to set context defaults");
|
||||
GST_OBJECT_UNLOCK (ffmpegdec);
|
||||
return FALSE;
|
||||
}
|
||||
ffmpegdec->context->opaque = ffmpegdec;
|
||||
|
||||
/* FIXME: https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/1474 */
|
||||
if ((oclass->in_plugin->capabilities & AV_CODEC_CAP_DELAY) != 0
|
||||
&& (oclass->in_plugin->id == AV_CODEC_ID_WMAV1
|
||||
|| oclass->in_plugin->id == AV_CODEC_ID_WMAV2)) {
|
||||
ffmpegdec->context->flags2 |= AV_CODEC_FLAG2_SKIP_MANUAL;
|
||||
}
|
||||
|
||||
GST_OBJECT_UNLOCK (ffmpegdec);
|
||||
|
||||
return TRUE;
|
||||
|
@ -240,8 +194,9 @@ gst_ffmpegauddec_stop (GstAudioDecoder * decoder)
|
|||
GstFFMpegAudDec *ffmpegdec = (GstFFMpegAudDec *) decoder;
|
||||
|
||||
GST_OBJECT_LOCK (ffmpegdec);
|
||||
gst_ffmpegauddec_close (ffmpegdec, FALSE);
|
||||
av_frame_free (&ffmpegdec->frame);
|
||||
g_free (ffmpegdec->padded);
|
||||
gst_ffmpegauddec_close (ffmpegdec);
|
||||
ffmpegdec->padded = NULL;
|
||||
ffmpegdec->padded_size = 0;
|
||||
GST_OBJECT_UNLOCK (ffmpegdec);
|
||||
|
@ -262,8 +217,6 @@ gst_ffmpegauddec_open (GstFFMpegAudDec * ffmpegdec)
|
|||
if (gst_ffmpeg_avcodec_open (ffmpegdec->context, oclass->in_plugin) < 0)
|
||||
goto could_not_open;
|
||||
|
||||
ffmpegdec->opened = TRUE;
|
||||
|
||||
GST_LOG_OBJECT (ffmpegdec, "Opened libav codec %s, id %d",
|
||||
oclass->in_plugin->name, oclass->in_plugin->id);
|
||||
|
||||
|
@ -274,7 +227,7 @@ gst_ffmpegauddec_open (GstFFMpegAudDec * ffmpegdec)
|
|||
/* ERRORS */
|
||||
could_not_open:
|
||||
{
|
||||
gst_ffmpegauddec_close (ffmpegdec, TRUE);
|
||||
gst_ffmpegauddec_close (ffmpegdec);
|
||||
GST_DEBUG_OBJECT (ffmpegdec, "avdec_%s: Failed to open libav codec",
|
||||
oclass->in_plugin->name);
|
||||
return FALSE;
|
||||
|
@ -321,14 +274,26 @@ gst_ffmpegauddec_set_format (GstAudioDecoder * decoder, GstCaps * caps)
|
|||
gst_caps_replace (&ffmpegdec->last_caps, caps);
|
||||
|
||||
/* close old session */
|
||||
if (ffmpegdec->opened) {
|
||||
if (ffmpegdec->context) {
|
||||
GST_OBJECT_UNLOCK (ffmpegdec);
|
||||
gst_ffmpegauddec_drain (ffmpegdec, FALSE);
|
||||
GST_OBJECT_LOCK (ffmpegdec);
|
||||
if (!gst_ffmpegauddec_close (ffmpegdec, TRUE)) {
|
||||
GST_OBJECT_UNLOCK (ffmpegdec);
|
||||
return FALSE;
|
||||
}
|
||||
gst_ffmpegauddec_close (ffmpegdec);
|
||||
}
|
||||
|
||||
ffmpegdec->context = avcodec_alloc_context3 (oclass->in_plugin);
|
||||
if (ffmpegdec->context == NULL) {
|
||||
GST_DEBUG_OBJECT (ffmpegdec, "Failed to allocate context");
|
||||
GST_OBJECT_UNLOCK (ffmpegdec);
|
||||
return FALSE;
|
||||
}
|
||||
ffmpegdec->context->opaque = ffmpegdec;
|
||||
|
||||
/* FIXME: https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/1474 */
|
||||
if ((oclass->in_plugin->capabilities & AV_CODEC_CAP_DELAY) != 0
|
||||
&& (oclass->in_plugin->id == AV_CODEC_ID_WMAV1
|
||||
|| oclass->in_plugin->id == AV_CODEC_ID_WMAV2)) {
|
||||
ffmpegdec->context->flags2 |= AV_CODEC_FLAG2_SKIP_MANUAL;
|
||||
}
|
||||
|
||||
/* get size and so */
|
||||
|
@ -586,7 +551,7 @@ gst_ffmpegauddec_frame (GstFFMpegAudDec * ffmpegdec, GstFlowReturn * ret,
|
|||
GstBuffer *outbuf = NULL;
|
||||
gboolean got_frame = FALSE;
|
||||
|
||||
if (G_UNLIKELY (ffmpegdec->context->codec == NULL))
|
||||
if (G_UNLIKELY (!ffmpegdec->context))
|
||||
goto no_codec;
|
||||
|
||||
*ret = GST_FLOW_OK;
|
||||
|
@ -630,6 +595,9 @@ gst_ffmpegauddec_drain (GstFFMpegAudDec * ffmpegdec, gboolean force)
|
|||
gboolean need_more_data = FALSE;
|
||||
gboolean got_frame;
|
||||
|
||||
if (!ffmpegdec->context)
|
||||
return GST_FLOW_OK;
|
||||
|
||||
if (avcodec_send_packet (ffmpegdec->context, NULL))
|
||||
goto send_packet_failed;
|
||||
|
||||
|
@ -672,7 +640,7 @@ gst_ffmpegauddec_flush (GstAudioDecoder * decoder, gboolean hard)
|
|||
{
|
||||
GstFFMpegAudDec *ffmpegdec = (GstFFMpegAudDec *) decoder;
|
||||
|
||||
if (ffmpegdec->opened) {
|
||||
if (ffmpegdec->context) {
|
||||
avcodec_flush_buffers (ffmpegdec->context);
|
||||
}
|
||||
}
|
||||
|
@ -697,7 +665,7 @@ gst_ffmpegauddec_handle_frame (GstAudioDecoder * decoder, GstBuffer * inbuf)
|
|||
|
||||
ffmpegdec = (GstFFMpegAudDec *) decoder;
|
||||
|
||||
if (G_UNLIKELY (!ffmpegdec->opened))
|
||||
if (G_UNLIKELY (!ffmpegdec->context))
|
||||
goto not_negotiated;
|
||||
|
||||
if (inbuf == NULL) {
|
||||
|
|
|
@ -34,7 +34,6 @@ struct _GstFFMpegAudDec
|
|||
|
||||
/* decoding */
|
||||
AVCodecContext *context;
|
||||
gboolean opened;
|
||||
|
||||
AVFrame *frame;
|
||||
|
||||
|
|
|
@ -161,10 +161,7 @@ gst_ffmpegaudenc_init (GstFFMpegAudEnc * ffmpegaudenc)
|
|||
GST_PAD_SET_ACCEPT_TEMPLATE (GST_AUDIO_ENCODER_SINK_PAD (ffmpegaudenc));
|
||||
|
||||
/* ffmpeg objects */
|
||||
ffmpegaudenc->context = avcodec_alloc_context3 (klass->in_plugin);
|
||||
ffmpegaudenc->refcontext = avcodec_alloc_context3 (klass->in_plugin);
|
||||
ffmpegaudenc->opened = FALSE;
|
||||
ffmpegaudenc->frame = av_frame_alloc ();
|
||||
|
||||
gst_audio_encoder_set_drainable (GST_AUDIO_ENCODER (ffmpegaudenc), TRUE);
|
||||
}
|
||||
|
@ -186,18 +183,12 @@ static gboolean
|
|||
gst_ffmpegaudenc_start (GstAudioEncoder * encoder)
|
||||
{
|
||||
GstFFMpegAudEnc *ffmpegaudenc = (GstFFMpegAudEnc *) encoder;
|
||||
GstFFMpegAudEncClass *oclass =
|
||||
(GstFFMpegAudEncClass *) G_OBJECT_GET_CLASS (ffmpegaudenc);
|
||||
|
||||
ffmpegaudenc->opened = FALSE;
|
||||
ffmpegaudenc->need_reopen = FALSE;
|
||||
|
||||
avcodec_free_context (&ffmpegaudenc->context);
|
||||
ffmpegaudenc->context = avcodec_alloc_context3 (oclass->in_plugin);
|
||||
if (ffmpegaudenc->context == NULL) {
|
||||
GST_DEBUG_OBJECT (ffmpegaudenc, "Failed to set context defaults");
|
||||
return FALSE;
|
||||
}
|
||||
av_frame_free (&ffmpegaudenc->frame);
|
||||
ffmpegaudenc->need_reopen = FALSE;
|
||||
|
||||
ffmpegaudenc->frame = av_frame_alloc ();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -208,8 +199,8 @@ gst_ffmpegaudenc_stop (GstAudioEncoder * encoder)
|
|||
GstFFMpegAudEnc *ffmpegaudenc = (GstFFMpegAudEnc *) encoder;
|
||||
|
||||
/* close old session */
|
||||
gst_ffmpeg_avcodec_close (ffmpegaudenc->context);
|
||||
ffmpegaudenc->opened = FALSE;
|
||||
avcodec_free_context (&ffmpegaudenc->context);
|
||||
av_frame_free (&ffmpegaudenc->frame);
|
||||
ffmpegaudenc->need_reopen = FALSE;
|
||||
|
||||
return TRUE;
|
||||
|
@ -220,7 +211,7 @@ gst_ffmpegaudenc_flush (GstAudioEncoder * encoder)
|
|||
{
|
||||
GstFFMpegAudEnc *ffmpegaudenc = (GstFFMpegAudEnc *) encoder;
|
||||
|
||||
if (ffmpegaudenc->opened) {
|
||||
if (ffmpegaudenc->context) {
|
||||
avcodec_flush_buffers (ffmpegaudenc->context);
|
||||
}
|
||||
}
|
||||
|
@ -239,14 +230,11 @@ gst_ffmpegaudenc_set_format (GstAudioEncoder * encoder, GstAudioInfo * info)
|
|||
ffmpegaudenc->need_reopen = FALSE;
|
||||
|
||||
/* close old session */
|
||||
if (ffmpegaudenc->opened) {
|
||||
avcodec_free_context (&ffmpegaudenc->context);
|
||||
ffmpegaudenc->opened = FALSE;
|
||||
ffmpegaudenc->context = avcodec_alloc_context3 (oclass->in_plugin);
|
||||
if (ffmpegaudenc->context == NULL) {
|
||||
GST_DEBUG_OBJECT (ffmpegaudenc, "Failed to set context defaults");
|
||||
return FALSE;
|
||||
}
|
||||
avcodec_free_context (&ffmpegaudenc->context);
|
||||
ffmpegaudenc->context = avcodec_alloc_context3 (oclass->in_plugin);
|
||||
if (ffmpegaudenc->context == NULL) {
|
||||
GST_DEBUG_OBJECT (ffmpegaudenc, "Failed to set context defaults");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gst_ffmpeg_cfg_fill_context (G_OBJECT (ffmpegaudenc), ffmpegaudenc->context);
|
||||
|
@ -298,12 +286,8 @@ gst_ffmpegaudenc_set_format (GstAudioEncoder * encoder, GstAudioInfo * info)
|
|||
/* open codec */
|
||||
if (gst_ffmpeg_avcodec_open (ffmpegaudenc->context, oclass->in_plugin) < 0) {
|
||||
gst_caps_unref (allowed_caps);
|
||||
avcodec_free_context (&ffmpegaudenc->context);
|
||||
GST_DEBUG_OBJECT (ffmpegaudenc, "avenc_%s: Failed to open FFMPEG codec",
|
||||
oclass->in_plugin->name);
|
||||
ffmpegaudenc->context = avcodec_alloc_context3 (oclass->in_plugin);
|
||||
if (ffmpegaudenc->context == NULL)
|
||||
GST_DEBUG_OBJECT (ffmpegaudenc, "Failed to set context defaults");
|
||||
|
||||
if ((oclass->in_plugin->capabilities & AV_CODEC_CAP_EXPERIMENTAL) &&
|
||||
ffmpegaudenc->context->strict_std_compliance !=
|
||||
|
@ -315,6 +299,7 @@ gst_ffmpegaudenc_set_format (GstAudioEncoder * encoder, GstAudioInfo * info)
|
|||
"or of good quality. If you must use it anyway, set the "
|
||||
"compliance property to experimental"));
|
||||
}
|
||||
avcodec_free_context (&ffmpegaudenc->context);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -326,9 +311,6 @@ gst_ffmpegaudenc_set_format (GstAudioEncoder * encoder, GstAudioInfo * info)
|
|||
gst_caps_unref (allowed_caps);
|
||||
avcodec_free_context (&ffmpegaudenc->context);
|
||||
GST_DEBUG ("Unsupported codec - no caps found");
|
||||
ffmpegaudenc->context = avcodec_alloc_context3 (oclass->in_plugin);
|
||||
if (ffmpegaudenc->context == NULL)
|
||||
GST_DEBUG_OBJECT (ffmpegaudenc, "Failed to set context defaults");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -337,6 +319,7 @@ gst_ffmpegaudenc_set_format (GstAudioEncoder * encoder, GstAudioInfo * info)
|
|||
gst_caps_unref (other_caps);
|
||||
if (gst_caps_is_empty (icaps)) {
|
||||
gst_caps_unref (icaps);
|
||||
avcodec_free_context (&ffmpegaudenc->context);
|
||||
return FALSE;
|
||||
}
|
||||
icaps = gst_caps_fixate (icaps);
|
||||
|
@ -345,9 +328,6 @@ gst_ffmpegaudenc_set_format (GstAudioEncoder * encoder, GstAudioInfo * info)
|
|||
icaps)) {
|
||||
avcodec_free_context (&ffmpegaudenc->context);
|
||||
gst_caps_unref (icaps);
|
||||
ffmpegaudenc->context = avcodec_alloc_context3 (oclass->in_plugin);
|
||||
if (ffmpegaudenc->context == NULL)
|
||||
GST_DEBUG_OBJECT (ffmpegaudenc, "Failed to set context defaults");
|
||||
return FALSE;
|
||||
}
|
||||
gst_caps_unref (icaps);
|
||||
|
@ -385,8 +365,6 @@ gst_ffmpegaudenc_set_format (GstAudioEncoder * encoder, GstAudioInfo * info)
|
|||
}
|
||||
|
||||
/* success! */
|
||||
ffmpegaudenc->opened = TRUE;
|
||||
ffmpegaudenc->need_reopen = FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -394,8 +372,7 @@ gst_ffmpegaudenc_set_format (GstAudioEncoder * encoder, GstAudioInfo * info)
|
|||
static void
|
||||
gst_ffmpegaudenc_free_avpacket (gpointer pkt)
|
||||
{
|
||||
av_packet_unref ((AVPacket *) pkt);
|
||||
g_free (pkt);
|
||||
av_packet_free ((AVPacket **) & pkt);
|
||||
}
|
||||
|
||||
typedef struct
|
||||
|
@ -596,8 +573,7 @@ gst_ffmpegaudenc_receive_packet (GstFFMpegAudEnc * ffmpegaudenc,
|
|||
|
||||
ctx = ffmpegaudenc->context;
|
||||
|
||||
pkt = g_new0 (AVPacket, 1);
|
||||
|
||||
pkt = av_packet_alloc ();
|
||||
res = avcodec_receive_packet (ctx, pkt);
|
||||
|
||||
if (res == 0) {
|
||||
|
@ -636,7 +612,7 @@ gst_ffmpegaudenc_receive_packet (GstFFMpegAudEnc * ffmpegaudenc,
|
|||
*got_packet = TRUE;
|
||||
} else {
|
||||
GST_LOG_OBJECT (ffmpegaudenc, "no output produced");
|
||||
g_free (pkt);
|
||||
av_packet_free (&pkt);
|
||||
ret = GST_FLOW_OK;
|
||||
*got_packet = FALSE;
|
||||
}
|
||||
|
@ -650,6 +626,9 @@ gst_ffmpegaudenc_drain (GstFFMpegAudEnc * ffmpegaudenc)
|
|||
GstFlowReturn ret = GST_FLOW_OK;
|
||||
gboolean got_packet;
|
||||
|
||||
if (!ffmpegaudenc->context)
|
||||
return GST_FLOW_OK;
|
||||
|
||||
ret = gst_ffmpegaudenc_send_frame (ffmpegaudenc, NULL);
|
||||
|
||||
if (ret == GST_FLOW_OK) {
|
||||
|
@ -683,7 +662,7 @@ gst_ffmpegaudenc_handle_frame (GstAudioEncoder * encoder, GstBuffer * inbuf)
|
|||
|
||||
ffmpegaudenc = (GstFFMpegAudEnc *) encoder;
|
||||
|
||||
if (G_UNLIKELY (!ffmpegaudenc->opened))
|
||||
if (G_UNLIKELY (!ffmpegaudenc->context))
|
||||
goto not_negotiated;
|
||||
|
||||
if (!inbuf)
|
||||
|
@ -752,7 +731,7 @@ gst_ffmpegaudenc_set_property (GObject * object,
|
|||
|
||||
ffmpegaudenc = (GstFFMpegAudEnc *) (object);
|
||||
|
||||
if (ffmpegaudenc->opened) {
|
||||
if (ffmpegaudenc->context) {
|
||||
GST_WARNING_OBJECT (ffmpegaudenc,
|
||||
"Can't change properties once encoder is setup !");
|
||||
return;
|
||||
|
|
|
@ -38,7 +38,6 @@ struct _GstFFMpegAudEnc
|
|||
|
||||
AVCodecContext *context;
|
||||
AVCodecContext *refcontext;
|
||||
gboolean opened;
|
||||
gboolean need_reopen;
|
||||
|
||||
AVFrame *frame;
|
||||
|
|
|
@ -488,10 +488,8 @@ gst_ffmpeg_cfg_install_properties (GObjectClass * klass, AVCodec * in_plugin,
|
|||
install_opts ((GObjectClass *) klass, &ctx->av_class, prop_id, flags,
|
||||
" (Generic codec option, might have no effect)", generic_overrides);
|
||||
|
||||
if (ctx) {
|
||||
gst_ffmpeg_avcodec_close (ctx);
|
||||
av_free (ctx);
|
||||
}
|
||||
if (ctx)
|
||||
avcodec_free_context (&ctx);
|
||||
}
|
||||
|
||||
static gint
|
||||
|
|
|
@ -3833,6 +3833,14 @@ gst_ffmpeg_formatid_to_caps (const gchar * format_name)
|
|||
caps = gst_caps_from_string ("audio/x-brstm");
|
||||
} else if (!strcmp (format_name, "bfstm")) {
|
||||
caps = gst_caps_from_string ("audio/x-bfstm");
|
||||
} else if (!strcmp (format_name, "avs")) {
|
||||
caps = gst_caps_from_string ("video/x-avs");
|
||||
} else if (!strcmp (format_name, "dsf")) {
|
||||
caps = gst_caps_from_string ("audio/x-dsf");
|
||||
} else if (!strcmp (format_name, "ea")) {
|
||||
caps = gst_caps_from_string ("video/x-ea");
|
||||
} else if (!strcmp (format_name, "film_cpk")) {
|
||||
caps = gst_caps_from_string ("video/x-film-cpk");
|
||||
} else {
|
||||
gchar *name;
|
||||
|
||||
|
@ -4029,6 +4037,18 @@ gst_ffmpeg_formatid_get_codecids (const gchar * format_name,
|
|||
|
||||
*video_codec_list = ivf_video_list;
|
||||
*audio_codec_list = ivf_audio_list;
|
||||
} else if ((!strcmp (format_name, "film_cpk"))) {
|
||||
static enum AVCodecID cpk_video_list[] = {
|
||||
AV_CODEC_ID_CINEPAK,
|
||||
AV_CODEC_ID_NONE
|
||||
};
|
||||
static enum AVCodecID cpk_audio_list[] = {
|
||||
AV_CODEC_ID_PCM_S16BE,
|
||||
AV_CODEC_ID_NONE
|
||||
};
|
||||
|
||||
*video_codec_list = cpk_video_list;
|
||||
*audio_codec_list = cpk_audio_list;
|
||||
} else if ((plugin->audio_codec != AV_CODEC_ID_NONE) ||
|
||||
(plugin->video_codec != AV_CODEC_ID_NONE)) {
|
||||
tmp_vlist[0] = plugin->video_codec;
|
||||
|
|
|
@ -225,14 +225,13 @@ gst_ffmpegdeinterlace_sink_setcaps (GstPad * pad, GstObject * parent,
|
|||
ctx->pix_fmt = AV_PIX_FMT_NB;
|
||||
gst_ffmpeg_caps_with_codectype (AVMEDIA_TYPE_VIDEO, caps, ctx);
|
||||
if (ctx->pix_fmt == AV_PIX_FMT_NB) {
|
||||
gst_ffmpeg_avcodec_close (ctx);
|
||||
av_free (ctx);
|
||||
avcodec_free_context (&ctx);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
deinterlace->pixfmt = ctx->pix_fmt;
|
||||
|
||||
av_free (ctx);
|
||||
avcodec_free_context (&ctx);
|
||||
|
||||
deinterlace->to_size =
|
||||
av_image_get_buffer_size (deinterlace->pixfmt, deinterlace->width,
|
||||
|
|
|
@ -67,7 +67,6 @@ struct _GstFFMpegDemux
|
|||
guint group_id;
|
||||
|
||||
AVFormatContext *context;
|
||||
gboolean opened;
|
||||
|
||||
GstFFStream *streams[MAX_STREAMS];
|
||||
|
||||
|
@ -273,7 +272,6 @@ gst_ffmpegdemux_init (GstFFMpegDemux * demux)
|
|||
demux->have_group_id = FALSE;
|
||||
demux->group_id = G_MAXUINT;
|
||||
|
||||
demux->opened = FALSE;
|
||||
demux->context = NULL;
|
||||
|
||||
for (n = 0; n < MAX_STREAMS; n++) {
|
||||
|
@ -324,7 +322,7 @@ gst_ffmpegdemux_close (GstFFMpegDemux * demux)
|
|||
gint n;
|
||||
GstEvent **event_p;
|
||||
|
||||
if (!demux->opened)
|
||||
if (!demux->context)
|
||||
return;
|
||||
|
||||
/* remove pads from ourselves */
|
||||
|
@ -353,12 +351,8 @@ gst_ffmpegdemux_close (GstFFMpegDemux * demux)
|
|||
gst_ffmpeg_pipe_close (demux->context->pb);
|
||||
demux->context->pb = NULL;
|
||||
avformat_close_input (&demux->context);
|
||||
if (demux->context)
|
||||
avformat_free_context (demux->context);
|
||||
demux->context = NULL;
|
||||
|
||||
GST_OBJECT_LOCK (demux);
|
||||
demux->opened = FALSE;
|
||||
event_p = &demux->seek_event;
|
||||
gst_event_replace (event_p, NULL);
|
||||
GST_OBJECT_UNLOCK (demux);
|
||||
|
@ -700,7 +694,7 @@ gst_ffmpegdemux_send_event (GstElement * element, GstEvent * event)
|
|||
switch (GST_EVENT_TYPE (event)) {
|
||||
case GST_EVENT_SEEK:
|
||||
GST_OBJECT_LOCK (demux);
|
||||
if (!demux->opened) {
|
||||
if (!demux->context) {
|
||||
GstEvent **event_p;
|
||||
|
||||
GST_DEBUG_OBJECT (demux, "caching seek event");
|
||||
|
@ -1309,7 +1303,6 @@ gst_ffmpegdemux_open (GstFFMpegDemux * demux)
|
|||
demux->segment.duration = demux->duration;
|
||||
|
||||
GST_OBJECT_LOCK (demux);
|
||||
demux->opened = TRUE;
|
||||
event = demux->seek_event;
|
||||
demux->seek_event = NULL;
|
||||
cached_events = demux->cached_events;
|
||||
|
@ -1366,69 +1359,21 @@ gst_ffmpegdemux_open (GstFFMpegDemux * demux)
|
|||
/* ERRORS */
|
||||
beach:
|
||||
{
|
||||
if (demux->context->pb) {
|
||||
if (demux->seekable)
|
||||
gst_ffmpegdata_close (demux->context->pb);
|
||||
else
|
||||
gst_ffmpeg_pipe_close (demux->context->pb);
|
||||
demux->context->pb = NULL;
|
||||
}
|
||||
avformat_close_input (&demux->context);
|
||||
|
||||
GST_ELEMENT_ERROR (demux, LIBRARY, FAILED, (NULL),
|
||||
("%s", gst_ffmpegdemux_averror (res)));
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
#define GST_FFMPEG_TYPE_FIND_SIZE 4096
|
||||
#define GST_FFMPEG_TYPE_FIND_MIN_SIZE 256
|
||||
|
||||
static void
|
||||
gst_ffmpegdemux_type_find (GstTypeFind * tf, gpointer priv)
|
||||
{
|
||||
const guint8 *data;
|
||||
AVInputFormat *in_plugin = (AVInputFormat *) priv;
|
||||
gint res = 0;
|
||||
guint64 length;
|
||||
GstCaps *sinkcaps;
|
||||
|
||||
/* We want GST_FFMPEG_TYPE_FIND_SIZE bytes, but if the file is shorter than
|
||||
* that we'll give it a try... */
|
||||
length = gst_type_find_get_length (tf);
|
||||
if (length == 0 || length > GST_FFMPEG_TYPE_FIND_SIZE)
|
||||
length = GST_FFMPEG_TYPE_FIND_SIZE;
|
||||
|
||||
/* The ffmpeg typefinders assume there's a certain minimum amount of data
|
||||
* and will happily do invalid memory access if there isn't, so let's just
|
||||
* skip the ffmpeg typefinders if the data available is too short
|
||||
* (in which case it's unlikely to be a media file anyway) */
|
||||
if (length < GST_FFMPEG_TYPE_FIND_MIN_SIZE) {
|
||||
GST_LOG ("not typefinding %" G_GUINT64_FORMAT " bytes, too short", length);
|
||||
return;
|
||||
}
|
||||
|
||||
GST_LOG ("typefinding %" G_GUINT64_FORMAT " bytes", length);
|
||||
if (in_plugin->read_probe &&
|
||||
(data = gst_type_find_peek (tf, 0, length)) != NULL) {
|
||||
AVProbeData probe_data;
|
||||
|
||||
probe_data.filename = "";
|
||||
probe_data.buf = (guint8 *) data;
|
||||
probe_data.buf_size = length;
|
||||
|
||||
res = in_plugin->read_probe (&probe_data);
|
||||
if (res > 0) {
|
||||
res = MAX (1, res * GST_TYPE_FIND_MAXIMUM / AVPROBE_SCORE_MAX);
|
||||
/* Restrict the probability for MPEG-TS streams, because there is
|
||||
* probably a better version in plugins-base, if the user has a recent
|
||||
* plugins-base (in fact we shouldn't even get here for ffmpeg mpegts or
|
||||
* mpegtsraw typefinders, since we blacklist them) */
|
||||
if (g_str_has_prefix (in_plugin->name, "mpegts"))
|
||||
res = MIN (res, GST_TYPE_FIND_POSSIBLE);
|
||||
|
||||
sinkcaps = gst_ffmpeg_formatid_to_caps (in_plugin->name);
|
||||
|
||||
GST_LOG ("libav typefinder '%s' suggests %" GST_PTR_FORMAT ", p=%u%%",
|
||||
in_plugin->name, sinkcaps, res);
|
||||
|
||||
gst_type_find_suggest (tf, res, sinkcaps);
|
||||
gst_caps_unref (sinkcaps);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Task */
|
||||
static void
|
||||
gst_ffmpegdemux_loop (GstFFMpegDemux * demux)
|
||||
|
@ -1447,7 +1392,7 @@ gst_ffmpegdemux_loop (GstFFMpegDemux * demux)
|
|||
gint64 pts;
|
||||
|
||||
/* open file if we didn't so already */
|
||||
if (!demux->opened)
|
||||
if (!demux->context)
|
||||
if (!gst_ffmpegdemux_open (demux))
|
||||
goto open_failed;
|
||||
|
||||
|
@ -1782,7 +1727,7 @@ gst_ffmpegdemux_sink_event (GstPad * sinkpad, GstObject * parent,
|
|||
* If the demuxer isn't opened, push straight away, since we'll
|
||||
* be waiting against a cond that will never be signalled. */
|
||||
if (GST_EVENT_IS_SERIALIZED (event)) {
|
||||
if (demux->opened) {
|
||||
if (demux->context) {
|
||||
GST_FFMPEG_PIPE_MUTEX_LOCK (ffpipe);
|
||||
while (!ffpipe->needed)
|
||||
GST_FFMPEG_PIPE_WAIT (ffpipe);
|
||||
|
@ -2055,7 +2000,6 @@ gst_ffmpegdemux_register (GstPlugin * plugin)
|
|||
while ((in_plugin = av_demuxer_iterate (&i))) {
|
||||
gchar *type_name, *typefind_name;
|
||||
gint rank;
|
||||
gboolean register_typefind_func = TRUE;
|
||||
|
||||
GST_LOG ("Attempting to handle libav demuxer plugin %s [%s]",
|
||||
in_plugin->name, in_plugin->long_name);
|
||||
|
@ -2102,42 +2046,6 @@ gst_ffmpegdemux_register (GstPlugin * plugin)
|
|||
!strcmp (in_plugin->name, "ffmetadata"))
|
||||
continue;
|
||||
|
||||
/* Don't use the typefind functions of formats for which we already have
|
||||
* better typefind functions */
|
||||
if (!strcmp (in_plugin->name, "mov,mp4,m4a,3gp,3g2,mj2") ||
|
||||
!strcmp (in_plugin->name, "ass") ||
|
||||
!strcmp (in_plugin->name, "avi") ||
|
||||
!strcmp (in_plugin->name, "asf") ||
|
||||
!strcmp (in_plugin->name, "mpegvideo") ||
|
||||
!strcmp (in_plugin->name, "mp3") ||
|
||||
!strcmp (in_plugin->name, "matroska") ||
|
||||
!strcmp (in_plugin->name, "matroska_webm") ||
|
||||
!strcmp (in_plugin->name, "matroska,webm") ||
|
||||
!strcmp (in_plugin->name, "mpeg") ||
|
||||
!strcmp (in_plugin->name, "wav") ||
|
||||
!strcmp (in_plugin->name, "au") ||
|
||||
!strcmp (in_plugin->name, "tta") ||
|
||||
!strcmp (in_plugin->name, "rm") ||
|
||||
!strcmp (in_plugin->name, "amr") ||
|
||||
!strcmp (in_plugin->name, "ogg") ||
|
||||
!strcmp (in_plugin->name, "aiff") ||
|
||||
!strcmp (in_plugin->name, "ape") ||
|
||||
!strcmp (in_plugin->name, "dv") ||
|
||||
!strcmp (in_plugin->name, "flv") ||
|
||||
!strcmp (in_plugin->name, "mpc") ||
|
||||
!strcmp (in_plugin->name, "mpc8") ||
|
||||
!strcmp (in_plugin->name, "mpegts") ||
|
||||
!strcmp (in_plugin->name, "mpegtsraw") ||
|
||||
!strcmp (in_plugin->name, "mxf") ||
|
||||
!strcmp (in_plugin->name, "nuv") ||
|
||||
!strcmp (in_plugin->name, "swf") ||
|
||||
!strcmp (in_plugin->name, "voc") ||
|
||||
!strcmp (in_plugin->name, "pva") ||
|
||||
!strcmp (in_plugin->name, "gif") ||
|
||||
!strcmp (in_plugin->name, "vc1test") ||
|
||||
!strcmp (in_plugin->name, "ivf"))
|
||||
register_typefind_func = FALSE;
|
||||
|
||||
/* Set the rank of demuxers known to work to MARGINAL.
|
||||
* Set demuxers for which we already have another implementation to NONE
|
||||
* Set All others to NONE*/
|
||||
|
@ -2214,11 +2122,7 @@ gst_ffmpegdemux_register (GstPlugin * plugin)
|
|||
else
|
||||
extensions = NULL;
|
||||
|
||||
if (!gst_element_register (plugin, type_name, rank, type) ||
|
||||
(register_typefind_func == TRUE &&
|
||||
!gst_type_find_register (plugin, typefind_name, rank,
|
||||
gst_ffmpegdemux_type_find, extensions, NULL,
|
||||
(gpointer) in_plugin, NULL))) {
|
||||
if (!gst_element_register (plugin, type_name, rank, type)) {
|
||||
g_warning ("Registration of type %s failed", type_name);
|
||||
g_free (type_name);
|
||||
g_free (typefind_name);
|
||||
|
|
|
@ -796,6 +796,7 @@ gst_ffmpegmux_change_state (GstElement * element, GstStateChange transition)
|
|||
if (ffmpegmux->opened) {
|
||||
ffmpegmux->opened = FALSE;
|
||||
gst_ffmpegdata_close (ffmpegmux->context->pb);
|
||||
ffmpegmux->context->pb = NULL;
|
||||
}
|
||||
break;
|
||||
case GST_STATE_CHANGE_READY_TO_NULL:
|
||||
|
|
|
@ -102,7 +102,11 @@ gst_ffmpegdata_read (void *priv_data, unsigned char *buf, int size)
|
|||
}
|
||||
|
||||
static int
|
||||
#if LIBAVUTIL_VERSION_MAJOR >= 59
|
||||
gst_ffmpegdata_write (void *priv_data, const uint8_t * buf, int size)
|
||||
#else
|
||||
gst_ffmpegdata_write (void *priv_data, uint8_t * buf, int size)
|
||||
#endif
|
||||
{
|
||||
GstProtocolInfo *info;
|
||||
GstBuffer *outbuf;
|
||||
|
|
|
@ -337,14 +337,7 @@ gst_ffmpegviddec_init (GstFFMpegVidDec * ffmpegdec)
|
|||
static void
|
||||
gst_ffmpegviddec_subinit (GstFFMpegVidDec * ffmpegdec)
|
||||
{
|
||||
GstFFMpegVidDecClass *klass =
|
||||
(GstFFMpegVidDecClass *) G_OBJECT_GET_CLASS (ffmpegdec);
|
||||
|
||||
/* some ffmpeg data */
|
||||
ffmpegdec->context = avcodec_alloc_context3 (klass->in_plugin);
|
||||
ffmpegdec->context->opaque = ffmpegdec;
|
||||
ffmpegdec->picture = av_frame_alloc ();
|
||||
ffmpegdec->opened = FALSE;
|
||||
ffmpegdec->skip_frame = ffmpegdec->lowres = 0;
|
||||
ffmpegdec->direct_rendering = DEFAULT_DIRECT_RENDERING;
|
||||
ffmpegdec->max_threads = DEFAULT_MAX_THREADS;
|
||||
|
@ -365,6 +358,8 @@ gst_ffmpegviddec_finalize (GObject * object)
|
|||
GstFFMpegVidDec *ffmpegdec = GST_FFMPEGVIDDEC (object);
|
||||
|
||||
av_frame_free (&ffmpegdec->picture);
|
||||
if (ffmpegdec->context)
|
||||
av_freep (&ffmpegdec->context->extradata);
|
||||
avcodec_free_context (&ffmpegdec->context);
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||
|
@ -395,37 +390,23 @@ gst_ffmpegviddec_context_set_flags2 (AVCodecContext * context, guint flags,
|
|||
}
|
||||
|
||||
/* with LOCK */
|
||||
static gboolean
|
||||
gst_ffmpegviddec_close (GstFFMpegVidDec * ffmpegdec, gboolean reset)
|
||||
static void
|
||||
gst_ffmpegviddec_close (GstFFMpegVidDec * ffmpegdec)
|
||||
{
|
||||
GstFFMpegVidDecClass *oclass;
|
||||
guint i;
|
||||
|
||||
oclass = GST_FFMPEGVIDDEC_GET_CLASS (ffmpegdec);
|
||||
|
||||
GST_LOG_OBJECT (ffmpegdec, "closing ffmpeg codec");
|
||||
|
||||
gst_caps_replace (&ffmpegdec->last_caps, NULL);
|
||||
|
||||
gst_ffmpeg_avcodec_close (ffmpegdec->context);
|
||||
ffmpegdec->opened = FALSE;
|
||||
if (ffmpegdec->context)
|
||||
av_freep (&ffmpegdec->context->extradata);
|
||||
avcodec_free_context (&ffmpegdec->context);
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (ffmpegdec->stride); i++)
|
||||
ffmpegdec->stride[i] = -1;
|
||||
|
||||
gst_buffer_replace (&ffmpegdec->palette, NULL);
|
||||
|
||||
av_freep (&ffmpegdec->context->extradata);
|
||||
if (reset) {
|
||||
avcodec_free_context (&ffmpegdec->context);
|
||||
ffmpegdec->context = avcodec_alloc_context3 (oclass->in_plugin);
|
||||
if (ffmpegdec->context == NULL) {
|
||||
GST_DEBUG_OBJECT (ffmpegdec, "Failed to set context defaults");
|
||||
return FALSE;
|
||||
}
|
||||
ffmpegdec->context->opaque = ffmpegdec;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* with LOCK */
|
||||
|
@ -443,8 +424,6 @@ gst_ffmpegviddec_open (GstFFMpegVidDec * ffmpegdec)
|
|||
for (i = 0; i < G_N_ELEMENTS (ffmpegdec->stride); i++)
|
||||
ffmpegdec->stride[i] = -1;
|
||||
|
||||
ffmpegdec->opened = TRUE;
|
||||
|
||||
GST_LOG_OBJECT (ffmpegdec, "Opened libav codec %s, id %d",
|
||||
oclass->in_plugin->name, oclass->in_plugin->id);
|
||||
|
||||
|
@ -460,7 +439,7 @@ gst_ffmpegviddec_open (GstFFMpegVidDec * ffmpegdec)
|
|||
/* ERRORS */
|
||||
could_not_open:
|
||||
{
|
||||
gst_ffmpegviddec_close (ffmpegdec, TRUE);
|
||||
gst_ffmpegviddec_close (ffmpegdec);
|
||||
GST_DEBUG_OBJECT (ffmpegdec, "avdec_%s: Failed to open libav codec",
|
||||
oclass->in_plugin->name);
|
||||
return FALSE;
|
||||
|
@ -537,14 +516,11 @@ gst_ffmpegviddec_set_format (GstVideoDecoder * decoder,
|
|||
}
|
||||
|
||||
/* close old session */
|
||||
if (ffmpegdec->opened) {
|
||||
if (ffmpegdec->context) {
|
||||
GST_OBJECT_UNLOCK (ffmpegdec);
|
||||
gst_ffmpegviddec_finish (decoder);
|
||||
GST_OBJECT_LOCK (ffmpegdec);
|
||||
if (!gst_ffmpegviddec_close (ffmpegdec, TRUE)) {
|
||||
GST_OBJECT_UNLOCK (ffmpegdec);
|
||||
return FALSE;
|
||||
}
|
||||
gst_ffmpegviddec_close (ffmpegdec);
|
||||
ffmpegdec->pic_pix_fmt = 0;
|
||||
ffmpegdec->pic_width = 0;
|
||||
ffmpegdec->pic_height = 0;
|
||||
|
@ -560,6 +536,14 @@ gst_ffmpegviddec_set_format (GstVideoDecoder * decoder,
|
|||
ffmpegdec->cur_multiview_flags = GST_VIDEO_MULTIVIEW_FLAGS_NONE;
|
||||
}
|
||||
|
||||
ffmpegdec->context = avcodec_alloc_context3 (oclass->in_plugin);
|
||||
if (ffmpegdec->context == NULL) {
|
||||
GST_DEBUG_OBJECT (ffmpegdec, "Failed to allocate context");
|
||||
GST_OBJECT_UNLOCK (ffmpegdec);
|
||||
return FALSE;
|
||||
}
|
||||
ffmpegdec->context->opaque = ffmpegdec;
|
||||
|
||||
gst_caps_replace (&ffmpegdec->last_caps, state->caps);
|
||||
|
||||
/* set buffer functions */
|
||||
|
@ -686,7 +670,9 @@ update_state:
|
|||
const gint fps_n = ffmpegdec->context->time_base.den;
|
||||
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(60, 31, 100)
|
||||
const gint ticks_per_frame =
|
||||
(ffmpegdec->context->
|
||||
(GST_VIDEO_INFO_IS_INTERLACED (&ffmpegdec->input_state->info)
|
||||
&& ffmpegdec->context->codec_descriptor
|
||||
&& ffmpegdec->context->
|
||||
codec_descriptor->props & AV_CODEC_PROP_FIELDS) ? 2 : 1;
|
||||
#else
|
||||
const gint ticks_per_frame = ffmpegdec->context->ticks_per_frame;
|
||||
|
@ -718,12 +704,18 @@ done:
|
|||
open_failed:
|
||||
{
|
||||
GST_DEBUG_OBJECT (ffmpegdec, "Failed to open");
|
||||
if (ffmpegdec->context)
|
||||
av_freep (&ffmpegdec->context->extradata);
|
||||
avcodec_free_context (&ffmpegdec->context);
|
||||
goto done;
|
||||
}
|
||||
nal_only_slice:
|
||||
{
|
||||
GST_ERROR_OBJECT (ffmpegdec,
|
||||
"Can't do NAL aligned H.264 with frame threading.");
|
||||
if (ffmpegdec->context)
|
||||
av_freep (&ffmpegdec->context->extradata);
|
||||
avcodec_free_context (&ffmpegdec->context);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
@ -1165,8 +1157,11 @@ static gboolean
|
|||
context_changed (GstFFMpegVidDec * ffmpegdec, AVCodecContext * context)
|
||||
{
|
||||
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(60, 31, 100)
|
||||
const gint ticks_per_frame = (context->codec_descriptor
|
||||
&& context->codec_descriptor->props & AV_CODEC_PROP_FIELDS) ? 2 : 1;
|
||||
const gint ticks_per_frame =
|
||||
(GST_VIDEO_INFO_IS_INTERLACED (&ffmpegdec->input_state->info)
|
||||
&& ffmpegdec->context->codec_descriptor
|
||||
&& ffmpegdec->context->
|
||||
codec_descriptor->props & AV_CODEC_PROP_FIELDS) ? 2 : 1;
|
||||
#else
|
||||
const gint ticks_per_frame = context->ticks_per_frame;
|
||||
#endif
|
||||
|
@ -1238,8 +1233,11 @@ update_video_context (GstFFMpegVidDec * ffmpegdec, AVCodecContext * context,
|
|||
ffmpegdec->pic_field_order_changed = FALSE;
|
||||
|
||||
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(60, 31, 100)
|
||||
const gint ticks_per_frame = (context->codec_descriptor
|
||||
&& context->codec_descriptor->props & AV_CODEC_PROP_FIELDS) ? 2 : 1;
|
||||
const gint ticks_per_frame =
|
||||
(GST_VIDEO_INFO_IS_INTERLACED (&ffmpegdec->input_state->info)
|
||||
&& ffmpegdec->context->codec_descriptor
|
||||
&& ffmpegdec->context->
|
||||
codec_descriptor->props & AV_CODEC_PROP_FIELDS) ? 2 : 1;
|
||||
#else
|
||||
const gint ticks_per_frame = context->ticks_per_frame;
|
||||
#endif
|
||||
|
@ -2119,7 +2117,7 @@ gst_ffmpegviddec_frame (GstFFMpegVidDec * ffmpegdec, GstVideoCodecFrame * frame,
|
|||
{
|
||||
gboolean got_frame = FALSE;
|
||||
|
||||
if (G_UNLIKELY (ffmpegdec->context->codec == NULL))
|
||||
if (G_UNLIKELY (!ffmpegdec->context))
|
||||
goto no_codec;
|
||||
|
||||
*ret = GST_FLOW_OK;
|
||||
|
@ -2149,7 +2147,7 @@ gst_ffmpegviddec_drain (GstVideoDecoder * decoder)
|
|||
GstFlowReturn ret = GST_FLOW_OK;
|
||||
gboolean got_frame = FALSE;
|
||||
|
||||
if (!ffmpegdec->opened)
|
||||
if (!ffmpegdec->context)
|
||||
return GST_FLOW_OK;
|
||||
|
||||
GST_VIDEO_DECODER_STREAM_UNLOCK (ffmpegdec);
|
||||
|
@ -2195,6 +2193,12 @@ gst_ffmpegviddec_handle_frame (GstVideoDecoder * decoder,
|
|||
GstFlowReturn ret = GST_FLOW_OK;
|
||||
AVPacket *packet;
|
||||
|
||||
if (G_UNLIKELY (!ffmpegdec->context)) {
|
||||
gst_video_codec_frame_unref (frame);
|
||||
GST_ERROR_OBJECT (ffmpegdec, "no codec context");
|
||||
return GST_FLOW_NOT_NEGOTIATED;
|
||||
}
|
||||
|
||||
GST_LOG_OBJECT (ffmpegdec,
|
||||
"Received new data of size %" G_GSIZE_FORMAT ", dts %" GST_TIME_FORMAT
|
||||
", pts:%" GST_TIME_FORMAT ", dur:%" GST_TIME_FORMAT,
|
||||
|
@ -2204,6 +2208,7 @@ gst_ffmpegviddec_handle_frame (GstVideoDecoder * decoder,
|
|||
if (!gst_buffer_map (frame->input_buffer, &minfo, GST_MAP_READ)) {
|
||||
GST_ELEMENT_ERROR (ffmpegdec, STREAM, DECODE, ("Decoding problem"),
|
||||
("Failed to map buffer for reading"));
|
||||
gst_video_codec_frame_unref (frame);
|
||||
return GST_FLOW_ERROR;
|
||||
}
|
||||
|
||||
|
@ -2312,19 +2317,13 @@ static gboolean
|
|||
gst_ffmpegviddec_start (GstVideoDecoder * decoder)
|
||||
{
|
||||
GstFFMpegVidDec *ffmpegdec = GST_FFMPEGVIDDEC (decoder);
|
||||
GstFFMpegVidDecClass *oclass;
|
||||
|
||||
oclass = GST_FFMPEGVIDDEC_GET_CLASS (ffmpegdec);
|
||||
|
||||
GST_OBJECT_LOCK (ffmpegdec);
|
||||
av_frame_free (&ffmpegdec->picture);
|
||||
if (ffmpegdec->context)
|
||||
av_freep (&ffmpegdec->context->extradata);
|
||||
avcodec_free_context (&ffmpegdec->context);
|
||||
ffmpegdec->context = avcodec_alloc_context3 (oclass->in_plugin);
|
||||
if (ffmpegdec->context == NULL) {
|
||||
GST_DEBUG_OBJECT (ffmpegdec, "Failed to set context defaults");
|
||||
GST_OBJECT_UNLOCK (ffmpegdec);
|
||||
return FALSE;
|
||||
}
|
||||
ffmpegdec->context->opaque = ffmpegdec;
|
||||
ffmpegdec->picture = av_frame_alloc ();
|
||||
GST_OBJECT_UNLOCK (ffmpegdec);
|
||||
|
||||
return TRUE;
|
||||
|
@ -2336,7 +2335,8 @@ gst_ffmpegviddec_stop (GstVideoDecoder * decoder)
|
|||
GstFFMpegVidDec *ffmpegdec = GST_FFMPEGVIDDEC (decoder);
|
||||
|
||||
GST_OBJECT_LOCK (ffmpegdec);
|
||||
gst_ffmpegviddec_close (ffmpegdec, FALSE);
|
||||
av_frame_free (&ffmpegdec->picture);
|
||||
gst_ffmpegviddec_close (ffmpegdec);
|
||||
GST_OBJECT_UNLOCK (ffmpegdec);
|
||||
g_free (ffmpegdec->padded);
|
||||
ffmpegdec->padded = NULL;
|
||||
|
@ -2390,7 +2390,7 @@ gst_ffmpegviddec_flush (GstVideoDecoder * decoder)
|
|||
{
|
||||
GstFFMpegVidDec *ffmpegdec = GST_FFMPEGVIDDEC (decoder);
|
||||
|
||||
if (ffmpegdec->opened) {
|
||||
if (ffmpegdec->context) {
|
||||
GST_LOG_OBJECT (decoder, "flushing buffers");
|
||||
GST_VIDEO_DECODER_STREAM_UNLOCK (ffmpegdec);
|
||||
avcodec_flush_buffers (ffmpegdec->context);
|
||||
|
@ -2579,11 +2579,10 @@ gst_ffmpegviddec_set_property (GObject * object,
|
|||
|
||||
switch (prop_id) {
|
||||
case PROP_LOWRES:
|
||||
ffmpegdec->lowres = ffmpegdec->context->lowres = g_value_get_enum (value);
|
||||
ffmpegdec->lowres = g_value_get_enum (value);
|
||||
break;
|
||||
case PROP_SKIPFRAME:
|
||||
ffmpegdec->skip_frame = ffmpegdec->context->skip_frame =
|
||||
g_value_get_enum (value);
|
||||
ffmpegdec->skip_frame = g_value_get_enum (value);
|
||||
break;
|
||||
case PROP_DIRECT_RENDERING:
|
||||
ffmpegdec->direct_rendering = g_value_get_boolean (value);
|
||||
|
|
|
@ -54,7 +54,6 @@ struct _GstFFMpegVidDec
|
|||
GstVideoMultiviewMode picture_multiview_mode;
|
||||
GstVideoMultiviewFlags picture_multiview_flags;
|
||||
gint stride[AV_NUM_DATA_POINTERS];
|
||||
gboolean opened;
|
||||
|
||||
/* current output pictures */
|
||||
enum AVPixelFormat pic_pix_fmt;
|
||||
|
|
|
@ -208,10 +208,7 @@ gst_ffmpegvidenc_init (GstFFMpegVidEnc * ffmpegenc)
|
|||
|
||||
GST_PAD_SET_ACCEPT_TEMPLATE (GST_VIDEO_ENCODER_SINK_PAD (ffmpegenc));
|
||||
|
||||
ffmpegenc->context = avcodec_alloc_context3 (klass->in_plugin);
|
||||
ffmpegenc->refcontext = avcodec_alloc_context3 (klass->in_plugin);
|
||||
ffmpegenc->picture = av_frame_alloc ();
|
||||
ffmpegenc->opened = FALSE;
|
||||
ffmpegenc->file = NULL;
|
||||
}
|
||||
|
||||
|
@ -222,10 +219,8 @@ gst_ffmpegvidenc_finalize (GObject * object)
|
|||
|
||||
/* clean up remaining allocated data */
|
||||
av_frame_free (&ffmpegenc->picture);
|
||||
gst_ffmpeg_avcodec_close (ffmpegenc->context);
|
||||
gst_ffmpeg_avcodec_close (ffmpegenc->refcontext);
|
||||
av_freep (&ffmpegenc->context);
|
||||
av_freep (&ffmpegenc->refcontext);
|
||||
avcodec_free_context (&ffmpegenc->context);
|
||||
avcodec_free_context (&ffmpegenc->refcontext);
|
||||
g_free (ffmpegenc->filename);
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||
|
@ -247,15 +242,13 @@ gst_ffmpegvidenc_set_format (GstVideoEncoder * encoder,
|
|||
ffmpegenc->need_reopen = FALSE;
|
||||
|
||||
/* close old session */
|
||||
if (ffmpegenc->opened) {
|
||||
avcodec_free_context (&ffmpegenc->context);
|
||||
ffmpegenc->opened = FALSE;
|
||||
ffmpegenc->context = avcodec_alloc_context3 (oclass->in_plugin);
|
||||
if (ffmpegenc->context == NULL) {
|
||||
GST_DEBUG_OBJECT (ffmpegenc, "Failed to set context defaults");
|
||||
return FALSE;
|
||||
}
|
||||
avcodec_free_context (&ffmpegenc->context);
|
||||
ffmpegenc->context = avcodec_alloc_context3 (oclass->in_plugin);
|
||||
if (ffmpegenc->context == NULL) {
|
||||
GST_DEBUG_OBJECT (ffmpegenc, "Failed to allocate context");
|
||||
return FALSE;
|
||||
}
|
||||
ffmpegenc->last_pts_ff = G_MININT64;
|
||||
|
||||
/* additional avcodec settings */
|
||||
gst_ffmpeg_cfg_fill_context (G_OBJECT (ffmpegenc), ffmpegenc->context);
|
||||
|
@ -402,7 +395,6 @@ gst_ffmpegvidenc_set_format (GstVideoEncoder * encoder,
|
|||
|
||||
/* success! */
|
||||
ffmpegenc->pts_offset = GST_CLOCK_TIME_NONE;
|
||||
ffmpegenc->opened = TRUE;
|
||||
|
||||
return TRUE;
|
||||
|
||||
|
@ -412,6 +404,7 @@ open_file_err:
|
|||
GST_ELEMENT_ERROR (ffmpegenc, RESOURCE, OPEN_WRITE,
|
||||
(("Could not open file \"%s\" for writing."), ffmpegenc->filename),
|
||||
GST_ERROR_SYSTEM);
|
||||
avcodec_free_context (&ffmpegenc->context);
|
||||
return FALSE;
|
||||
}
|
||||
file_read_err:
|
||||
|
@ -419,6 +412,7 @@ file_read_err:
|
|||
GST_ELEMENT_ERROR (ffmpegenc, RESOURCE, READ,
|
||||
(("Could not get contents of file \"%s\"."), ffmpegenc->filename),
|
||||
GST_ERROR_SYSTEM);
|
||||
avcodec_free_context (&ffmpegenc->context);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -426,12 +420,12 @@ insane_timebase:
|
|||
{
|
||||
GST_ERROR_OBJECT (ffmpegenc, "Rejecting time base %d/%d",
|
||||
ffmpegenc->context->time_base.den, ffmpegenc->context->time_base.num);
|
||||
goto cleanup_stats_in;
|
||||
goto close_codec;
|
||||
}
|
||||
unsupported_codec:
|
||||
{
|
||||
GST_DEBUG ("Unsupported codec - no caps found");
|
||||
goto cleanup_stats_in;
|
||||
goto close_codec;
|
||||
}
|
||||
open_codec_fail:
|
||||
{
|
||||
|
@ -456,15 +450,13 @@ bad_input_fmt:
|
|||
}
|
||||
close_codec:
|
||||
{
|
||||
if (ffmpegenc->context)
|
||||
g_free (ffmpegenc->context->stats_in);
|
||||
if (ffmpegenc->file) {
|
||||
fclose (ffmpegenc->file);
|
||||
ffmpegenc->file = NULL;
|
||||
}
|
||||
avcodec_free_context (&ffmpegenc->context);
|
||||
ffmpegenc->context = avcodec_alloc_context3 (oclass->in_plugin);
|
||||
if (ffmpegenc->context == NULL)
|
||||
GST_DEBUG_OBJECT (ffmpegenc, "Failed to set context defaults");
|
||||
goto cleanup_stats_in;
|
||||
}
|
||||
cleanup_stats_in:
|
||||
{
|
||||
g_free (ffmpegenc->context->stats_in);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
@ -483,8 +475,7 @@ gst_ffmpegvidenc_propose_allocation (GstVideoEncoder * encoder,
|
|||
static void
|
||||
gst_ffmpegvidenc_free_avpacket (gpointer pkt)
|
||||
{
|
||||
av_packet_unref ((AVPacket *) pkt);
|
||||
g_free (pkt);
|
||||
av_packet_free ((AVPacket **) & pkt);
|
||||
}
|
||||
|
||||
typedef struct
|
||||
|
@ -560,6 +551,7 @@ gst_ffmpegvidenc_send_frame (GstFFMpegVidEnc * ffmpegenc,
|
|||
gint res;
|
||||
GstFlowReturn ret = GST_FLOW_ERROR;
|
||||
AVFrame *picture = NULL;
|
||||
GstClockTime pts, pts_running_time;
|
||||
|
||||
if (!frame)
|
||||
goto send_frame;
|
||||
|
@ -629,26 +621,46 @@ gst_ffmpegvidenc_send_frame (GstFFMpegVidEnc * ffmpegenc,
|
|||
picture->width = GST_VIDEO_FRAME_WIDTH (&buffer_info->vframe);
|
||||
picture->height = GST_VIDEO_FRAME_HEIGHT (&buffer_info->vframe);
|
||||
|
||||
// Use the running time to calculate a PTS that is passed to the encoder.
|
||||
// This ensures that it is increasing even if there are segment changes and
|
||||
// makes it unnecessary to drain the encoder on every segment change.
|
||||
pts = frame->pts;
|
||||
pts_running_time =
|
||||
gst_segment_to_running_time (&GST_VIDEO_ENCODER
|
||||
(ffmpegenc)->input_segment, GST_FORMAT_TIME, pts);
|
||||
|
||||
if (ffmpegenc->pts_offset == GST_CLOCK_TIME_NONE) {
|
||||
ffmpegenc->pts_offset = frame->pts;
|
||||
ffmpegenc->pts_offset = pts_running_time;
|
||||
}
|
||||
|
||||
if (frame->pts == GST_CLOCK_TIME_NONE) {
|
||||
if (pts_running_time == GST_CLOCK_TIME_NONE) {
|
||||
picture->pts = AV_NOPTS_VALUE;
|
||||
} else if (frame->pts < ffmpegenc->pts_offset) {
|
||||
} else if (pts_running_time < ffmpegenc->pts_offset) {
|
||||
GST_ERROR_OBJECT (ffmpegenc, "PTS is going backwards");
|
||||
picture->pts = AV_NOPTS_VALUE;
|
||||
} else {
|
||||
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(60, 31, 100)
|
||||
const gint ticks_per_frame = (ffmpegenc->context->codec_descriptor
|
||||
const gint ticks_per_frame =
|
||||
(GST_VIDEO_INFO_IS_INTERLACED (&ffmpegenc->input_state->info)
|
||||
&& ffmpegenc->context->codec_descriptor
|
||||
&& ffmpegenc->context->
|
||||
codec_descriptor->props & AV_CODEC_PROP_FIELDS) ? 2 : 1;
|
||||
#else
|
||||
const gint ticks_per_frame = ffmpegenc->context->ticks_per_frame;
|
||||
#endif
|
||||
picture->pts =
|
||||
gst_ffmpeg_time_gst_to_ff ((frame->pts - ffmpegenc->pts_offset) /
|
||||
gst_ffmpeg_time_gst_to_ff ((pts_running_time - ffmpegenc->pts_offset) /
|
||||
ticks_per_frame, ffmpegenc->context->time_base);
|
||||
|
||||
// Certain codecs require always increasing PTS to work correctly. This
|
||||
// affects at least all MPEG1/2/4 based encoders.
|
||||
if (ffmpegenc->last_pts_ff == G_MININT64
|
||||
|| picture->pts > ffmpegenc->last_pts_ff) {
|
||||
ffmpegenc->last_pts_ff = picture->pts;
|
||||
} else {
|
||||
ffmpegenc->last_pts_ff += 1;
|
||||
picture->pts = ffmpegenc->last_pts_ff;
|
||||
}
|
||||
}
|
||||
|
||||
send_frame:
|
||||
|
@ -692,18 +704,18 @@ gst_ffmpegvidenc_receive_packet (GstFFMpegVidEnc * ffmpegenc,
|
|||
|
||||
*got_packet = FALSE;
|
||||
|
||||
pkt = g_new0 (AVPacket, 1);
|
||||
|
||||
pkt = av_packet_alloc ();
|
||||
res = avcodec_receive_packet (ffmpegenc->context, pkt);
|
||||
|
||||
if (res == AVERROR (EAGAIN)) {
|
||||
g_free (pkt);
|
||||
av_packet_free (&pkt);
|
||||
goto done;
|
||||
} else if (res == AVERROR_EOF) {
|
||||
g_free (pkt);
|
||||
av_packet_free (&pkt);
|
||||
ret = GST_FLOW_EOS;
|
||||
goto done;
|
||||
} else if (res < 0) {
|
||||
av_packet_free (&pkt);
|
||||
ret = GST_FLOW_ERROR;
|
||||
goto done;
|
||||
}
|
||||
|
@ -743,7 +755,7 @@ gst_ffmpegvidenc_receive_packet (GstFFMpegVidEnc * ffmpegenc,
|
|||
ffmpegenc->context->time_base);
|
||||
|
||||
if (gst_pts_dts_diff > frame->pts)
|
||||
frame->pts = 0;
|
||||
frame->dts = 0;
|
||||
else
|
||||
frame->dts = frame->pts - gst_pts_dts_diff;
|
||||
} else {
|
||||
|
@ -767,7 +779,7 @@ gst_ffmpegvidenc_handle_frame (GstVideoEncoder * encoder,
|
|||
GstFlowReturn ret;
|
||||
gboolean got_packet;
|
||||
|
||||
/* endoder was drained or flushed, and ffmpeg encoder doesn't support
|
||||
/* encoder was drained or flushed, and ffmpeg encoder doesn't support
|
||||
* flushing. We need to re-open encoder then */
|
||||
if (ffmpegenc->need_reopen) {
|
||||
gboolean reopen_ret;
|
||||
|
@ -778,6 +790,7 @@ gst_ffmpegvidenc_handle_frame (GstVideoEncoder * encoder,
|
|||
if (!ffmpegenc->input_state) {
|
||||
GST_ERROR_OBJECT (ffmpegenc,
|
||||
"Cannot re-open encoder without input state");
|
||||
gst_video_codec_frame_unref (frame);
|
||||
return GST_FLOW_NOT_NEGOTIATED;
|
||||
}
|
||||
|
||||
|
@ -787,6 +800,7 @@ gst_ffmpegvidenc_handle_frame (GstVideoEncoder * encoder,
|
|||
|
||||
if (!reopen_ret) {
|
||||
GST_ERROR_OBJECT (ffmpegenc, "Couldn't re-open encoder");
|
||||
gst_video_codec_frame_unref (frame);
|
||||
return GST_FLOW_NOT_NEGOTIATED;
|
||||
}
|
||||
}
|
||||
|
@ -831,7 +845,7 @@ gst_ffmpegvidenc_flush_buffers (GstFFMpegVidEnc * ffmpegenc, gboolean send)
|
|||
GST_DEBUG_OBJECT (ffmpegenc, "flushing buffers with sending %d", send);
|
||||
|
||||
/* no need to empty codec if there is none */
|
||||
if (!ffmpegenc->opened)
|
||||
if (!ffmpegenc->context)
|
||||
goto done;
|
||||
|
||||
ret = gst_ffmpegvidenc_send_frame (ffmpegenc, NULL);
|
||||
|
@ -867,7 +881,7 @@ gst_ffmpegvidenc_set_property (GObject * object,
|
|||
|
||||
ffmpegenc = (GstFFMpegVidEnc *) (object);
|
||||
|
||||
if (ffmpegenc->opened) {
|
||||
if (ffmpegenc->context) {
|
||||
GST_WARNING_OBJECT (ffmpegenc,
|
||||
"Can't change properties once decoder is setup !");
|
||||
return;
|
||||
|
@ -921,7 +935,7 @@ gst_ffmpegvidenc_flush (GstVideoEncoder * encoder)
|
|||
{
|
||||
GstFFMpegVidEnc *ffmpegenc = (GstFFMpegVidEnc *) encoder;
|
||||
|
||||
if (ffmpegenc->opened) {
|
||||
if (ffmpegenc->context) {
|
||||
avcodec_flush_buffers (ffmpegenc->context);
|
||||
ffmpegenc->pts_offset = GST_CLOCK_TIME_NONE;
|
||||
}
|
||||
|
@ -933,20 +947,19 @@ static gboolean
|
|||
gst_ffmpegvidenc_start (GstVideoEncoder * encoder)
|
||||
{
|
||||
GstFFMpegVidEnc *ffmpegenc = (GstFFMpegVidEnc *) encoder;
|
||||
GstFFMpegVidEncClass *oclass =
|
||||
(GstFFMpegVidEncClass *) G_OBJECT_GET_CLASS (ffmpegenc);
|
||||
|
||||
ffmpegenc->opened = FALSE;
|
||||
ffmpegenc->need_reopen = FALSE;
|
||||
|
||||
/* close old session */
|
||||
avcodec_free_context (&ffmpegenc->context);
|
||||
ffmpegenc->context = avcodec_alloc_context3 (oclass->in_plugin);
|
||||
if (ffmpegenc->context == NULL) {
|
||||
GST_DEBUG_OBJECT (ffmpegenc, "Failed to set context defaults");
|
||||
return FALSE;
|
||||
if (ffmpegenc->file) {
|
||||
fclose (ffmpegenc->file);
|
||||
ffmpegenc->file = NULL;
|
||||
}
|
||||
if (ffmpegenc->context)
|
||||
g_free (ffmpegenc->context->stats_in);
|
||||
avcodec_free_context (&ffmpegenc->context);
|
||||
av_frame_free (&ffmpegenc->picture);
|
||||
ffmpegenc->need_reopen = FALSE;
|
||||
|
||||
ffmpegenc->picture = av_frame_alloc ();
|
||||
gst_video_encoder_set_min_pts (encoder, GST_SECOND * 60 * 60 * 1000);
|
||||
|
||||
return TRUE;
|
||||
|
@ -958,8 +971,14 @@ gst_ffmpegvidenc_stop (GstVideoEncoder * encoder)
|
|||
GstFFMpegVidEnc *ffmpegenc = (GstFFMpegVidEnc *) encoder;
|
||||
|
||||
gst_ffmpegvidenc_flush_buffers (ffmpegenc, FALSE);
|
||||
gst_ffmpeg_avcodec_close (ffmpegenc->context);
|
||||
ffmpegenc->opened = FALSE;
|
||||
if (ffmpegenc->context)
|
||||
g_free (ffmpegenc->context->stats_in);
|
||||
if (ffmpegenc->file) {
|
||||
fclose (ffmpegenc->file);
|
||||
ffmpegenc->file = NULL;
|
||||
}
|
||||
avcodec_free_context (&ffmpegenc->context);
|
||||
av_frame_free (&ffmpegenc->picture);
|
||||
ffmpegenc->need_reopen = FALSE;
|
||||
|
||||
if (ffmpegenc->input_state) {
|
||||
|
|
|
@ -41,7 +41,7 @@ struct _GstFFMpegVidEnc
|
|||
AVCodecContext *context;
|
||||
AVFrame *picture;
|
||||
GstClockTime pts_offset;
|
||||
gboolean opened;
|
||||
gint64 last_pts_ff;
|
||||
gboolean need_reopen;
|
||||
gboolean discont;
|
||||
guint pass;
|
||||
|
|
|
@ -5516,6 +5516,134 @@ tap_type_find (GstTypeFind * tf, gpointer unused)
|
|||
}
|
||||
}
|
||||
|
||||
/*** audio/x-brstm ***/
|
||||
|
||||
static GstStaticCaps brstm_caps = GST_STATIC_CAPS ("audio/x-brstm");
|
||||
|
||||
#define BRSTM_CAPS (gst_static_caps_get(&brstm_caps))
|
||||
static void
|
||||
brstm_type_find (GstTypeFind * tf, gpointer unused)
|
||||
{
|
||||
const guint8 *data = gst_type_find_peek (tf, 0, 8);
|
||||
|
||||
if (data) {
|
||||
if (GST_READ_UINT32_LE (data) != GST_MAKE_FOURCC ('R', 'S', 'T', 'M'))
|
||||
return;
|
||||
if (GST_READ_UINT32_LE (data + 4) != 0xfffe
|
||||
&& GST_READ_UINT32_LE (data + 4) != 0xfeff)
|
||||
return;
|
||||
gst_type_find_suggest (tf, GST_TYPE_FIND_MAXIMUM, BRSTM_CAPS);
|
||||
}
|
||||
}
|
||||
|
||||
/*** audio/x-bfstm ***/
|
||||
|
||||
static GstStaticCaps bfstm_caps = GST_STATIC_CAPS ("audio/x-bfstm");
|
||||
|
||||
#define BFSTM_CAPS (gst_static_caps_get(&bfstm_caps))
|
||||
static void
|
||||
bfstm_type_find (GstTypeFind * tf, gpointer unused)
|
||||
{
|
||||
const guint8 *data = gst_type_find_peek (tf, 0, 8);
|
||||
|
||||
if (data) {
|
||||
if (GST_READ_UINT32_LE (data) != GST_MAKE_FOURCC ('F', 'S', 'T', 'M') &&
|
||||
GST_READ_UINT32_LE (data) != GST_MAKE_FOURCC ('C', 'S', 'T', 'M'))
|
||||
return;
|
||||
if (GST_READ_UINT32_LE (data + 4) != 0xfffe
|
||||
&& GST_READ_UINT32_LE (data + 4) != 0xfeff)
|
||||
return;
|
||||
gst_type_find_suggest (tf, GST_TYPE_FIND_MAXIMUM, BFSTM_CAPS);
|
||||
}
|
||||
}
|
||||
|
||||
/*** audio/x-dsf ***/
|
||||
|
||||
static GstStaticCaps dsf_caps = GST_STATIC_CAPS ("audio/x-dsf");
|
||||
|
||||
#define DSF_CAPS (gst_static_caps_get(&dsf_caps))
|
||||
static void
|
||||
dsf_type_find (GstTypeFind * tf, gpointer unused)
|
||||
{
|
||||
const guint8 *data = gst_type_find_peek (tf, 0, 12);
|
||||
|
||||
if (data) {
|
||||
if (memcmp (data, "DSD ", 4) != 0)
|
||||
return;
|
||||
if (GST_READ_UINT64_BE (data + 4) == 28)
|
||||
return;
|
||||
|
||||
gst_type_find_suggest (tf, GST_TYPE_FIND_MAXIMUM, DSF_CAPS);
|
||||
}
|
||||
}
|
||||
|
||||
/*** video/x-ea ***/
|
||||
|
||||
static GstStaticCaps ea_caps = GST_STATIC_CAPS ("video/x-ea");
|
||||
|
||||
#define EA_CAPS (gst_static_caps_get(&ea_caps))
|
||||
static void
|
||||
ea_type_find (GstTypeFind * tf, gpointer unused)
|
||||
{
|
||||
const guint8 *data = gst_type_find_peek (tf, 0, 8);
|
||||
|
||||
if (data) {
|
||||
static const guint32 ea_fourccs[] = {
|
||||
GST_MAKE_FOURCC ('I', 'S', 'N', 'h'),
|
||||
GST_MAKE_FOURCC ('S', 'C', 'H', 'l'),
|
||||
GST_MAKE_FOURCC ('S', 'E', 'A', 'D'),
|
||||
GST_MAKE_FOURCC ('S', 'H', 'E', 'N'),
|
||||
GST_MAKE_FOURCC ('k', 'V', 'G', 'T'),
|
||||
GST_MAKE_FOURCC ('M', 'A', 'D', 'k'),
|
||||
GST_MAKE_FOURCC ('M', 'P', 'C', 'h'),
|
||||
GST_MAKE_FOURCC ('M', 'V', 'h', 'd'),
|
||||
GST_MAKE_FOURCC ('M', 'V', 'I', 'h'),
|
||||
GST_MAKE_FOURCC ('A', 'V', 'P', '6'),
|
||||
};
|
||||
|
||||
guint32 fourcc = GST_READ_UINT32_LE (data);
|
||||
gboolean found = FALSE;
|
||||
|
||||
for (gsize i = 0; i < G_N_ELEMENTS (ea_fourccs); i++) {
|
||||
if (fourcc == ea_fourccs[i]) {
|
||||
found = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
return;
|
||||
|
||||
guint32 size = GST_READ_UINT32_LE (data + 4);
|
||||
gboolean big_endian = size > 0x000fffff;
|
||||
if (big_endian)
|
||||
size = GUINT32_SWAP_LE_BE (size);
|
||||
if (size > 0xfffff || size < 8)
|
||||
return;
|
||||
|
||||
gst_type_find_suggest (tf, GST_TYPE_FIND_MAXIMUM, EA_CAPS);
|
||||
}
|
||||
}
|
||||
|
||||
/*** video/x-film-cpk ***/
|
||||
|
||||
static GstStaticCaps film_cpk_caps = GST_STATIC_CAPS ("video/x-film-cpk");
|
||||
|
||||
#define FILM_CPK_CAPS (gst_static_caps_get(&film_cpk_caps))
|
||||
static void
|
||||
film_cpk_type_find (GstTypeFind * tf, gpointer unused)
|
||||
{
|
||||
const guint8 *data = gst_type_find_peek (tf, 0, 20);
|
||||
|
||||
if (data) {
|
||||
if (GST_READ_UINT32_LE (data) != GST_MAKE_FOURCC ('F', 'I', 'L', 'M'))
|
||||
return;
|
||||
if (GST_READ_UINT32_LE (data + 16) != GST_MAKE_FOURCC ('F', 'D', 'S', 'C'))
|
||||
return;
|
||||
|
||||
gst_type_find_suggest (tf, GST_TYPE_FIND_MAXIMUM, FILM_CPK_CAPS);
|
||||
}
|
||||
}
|
||||
|
||||
/*** video/vivo ***/
|
||||
|
||||
static GstStaticCaps vivo_caps = GST_STATIC_CAPS ("video/vivo");
|
||||
|
@ -6216,3 +6344,13 @@ GST_TYPE_FIND_REGISTER_DEFINE (aa, "audio/audible", GST_RANK_MARGINAL,
|
|||
aa_type_find, "aa,aax", AA_CAPS, NULL, NULL);
|
||||
GST_TYPE_FIND_REGISTER_DEFINE (tap, "audio/x-tap-tap", GST_RANK_PRIMARY,
|
||||
tap_type_find, "tap", TAP_CAPS, NULL, NULL);
|
||||
GST_TYPE_FIND_REGISTER_DEFINE (brstm, "audio/x-brstm", GST_RANK_SECONDARY,
|
||||
brstm_type_find, "brstm", BRSTM_CAPS, NULL, NULL);
|
||||
GST_TYPE_FIND_REGISTER_DEFINE (bfstm, "audio/x-bfstm", GST_RANK_SECONDARY,
|
||||
bfstm_type_find, "bfstm,bcstm", BFSTM_CAPS, NULL, NULL);
|
||||
GST_TYPE_FIND_REGISTER_DEFINE (dsf, "audio/x-dsf", GST_RANK_SECONDARY,
|
||||
dsf_type_find, NULL, DSF_CAPS, NULL, NULL);
|
||||
GST_TYPE_FIND_REGISTER_DEFINE (ea, "video/x-ea", GST_RANK_SECONDARY,
|
||||
ea_type_find, NULL, EA_CAPS, NULL, NULL);
|
||||
GST_TYPE_FIND_REGISTER_DEFINE (film_cpk, "video/x-film-cpk", GST_RANK_SECONDARY,
|
||||
film_cpk_type_find, "cpk", FILM_CPK_CAPS, NULL, NULL);
|
||||
|
|
|
@ -42,6 +42,7 @@ plugin_init (GstPlugin * plugin)
|
|||
/* must use strings, macros don't accept initializers */
|
||||
|
||||
/*Riff Type find register */
|
||||
GST_TYPE_FIND_REGISTER (fourxm, plugin);
|
||||
GST_TYPE_FIND_REGISTER (avi, plugin);
|
||||
GST_TYPE_FIND_REGISTER (qcp, plugin);
|
||||
GST_TYPE_FIND_REGISTER (cdxa, plugin);
|
||||
|
@ -51,6 +52,7 @@ plugin_init (GstPlugin * plugin)
|
|||
|
||||
/*'Start with' Type find register */
|
||||
GST_TYPE_FIND_REGISTER (asf, plugin);
|
||||
GST_TYPE_FIND_REGISTER (avs, plugin);
|
||||
GST_TYPE_FIND_REGISTER (vcd, plugin);
|
||||
GST_TYPE_FIND_REGISTER (imelody, plugin);
|
||||
GST_TYPE_FIND_REGISTER (scc, plugin);
|
||||
|
@ -203,6 +205,11 @@ plugin_init (GstPlugin * plugin)
|
|||
GST_TYPE_FIND_REGISTER (pva, plugin);
|
||||
GST_TYPE_FIND_REGISTER (aa, plugin);
|
||||
GST_TYPE_FIND_REGISTER (tap, plugin);
|
||||
GST_TYPE_FIND_REGISTER (brstm, plugin);
|
||||
GST_TYPE_FIND_REGISTER (bfstm, plugin);
|
||||
GST_TYPE_FIND_REGISTER (dsf, plugin);
|
||||
GST_TYPE_FIND_REGISTER (ea, plugin);
|
||||
GST_TYPE_FIND_REGISTER (film_cpk, plugin);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
@ -41,9 +41,11 @@ GST_TYPE_FIND_REGISTER_DECLARE (cdxa);
|
|||
GST_TYPE_FIND_REGISTER_DECLARE (riff_mid);
|
||||
GST_TYPE_FIND_REGISTER_DECLARE (wav);
|
||||
GST_TYPE_FIND_REGISTER_DECLARE (webp);
|
||||
GST_TYPE_FIND_REGISTER_DECLARE (fourxm);
|
||||
|
||||
/*'Start with' type find declaration */
|
||||
GST_TYPE_FIND_REGISTER_DECLARE (asf);
|
||||
GST_TYPE_FIND_REGISTER_DECLARE (avs);
|
||||
GST_TYPE_FIND_REGISTER_DECLARE (vcd);
|
||||
GST_TYPE_FIND_REGISTER_DECLARE (imelody);
|
||||
GST_TYPE_FIND_REGISTER_DECLARE (scc);
|
||||
|
@ -195,5 +197,10 @@ GST_TYPE_FIND_REGISTER_DECLARE (ssa);
|
|||
GST_TYPE_FIND_REGISTER_DECLARE (pva);
|
||||
GST_TYPE_FIND_REGISTER_DECLARE (aa);
|
||||
GST_TYPE_FIND_REGISTER_DECLARE (tap);
|
||||
GST_TYPE_FIND_REGISTER_DECLARE (brstm);
|
||||
GST_TYPE_FIND_REGISTER_DECLARE (bfstm);
|
||||
GST_TYPE_FIND_REGISTER_DECLARE (dsf);
|
||||
GST_TYPE_FIND_REGISTER_DECLARE (ea);
|
||||
GST_TYPE_FIND_REGISTER_DECLARE (film_cpk);
|
||||
|
||||
#endif //__GST_TYPE_FIND_FUNCTIONS_PLUGIN_H__
|
||||
|
|
|
@ -81,3 +81,5 @@ TYPE_FIND_REGISTER_RIFF_DEFINE (wav, "audio/x-wav", GST_RANK_PRIMARY, "wav",
|
|||
"WAVE");
|
||||
TYPE_FIND_REGISTER_RIFF_DEFINE (webp, "image/webp", GST_RANK_PRIMARY,
|
||||
"webp", "WEBP");
|
||||
TYPE_FIND_REGISTER_RIFF_DEFINE (fourxm, "video/x-4xm", GST_RANK_PRIMARY,
|
||||
NULL, "4XMV");
|
||||
|
|
|
@ -177,3 +177,5 @@ TYPE_FIND_REGISTER_START_WITH_DEFINE (xi, "audio/x-xi", GST_RANK_SECONDARY,
|
|||
"xi", "Extended Instrument: ", 21, GST_TYPE_FIND_MAXIMUM);
|
||||
TYPE_FIND_REGISTER_START_WITH_DEFINE (dmp, "audio/x-tap-dmp",
|
||||
GST_RANK_SECONDARY, "dmp", "DC2N-TAP-RAW", 12, GST_TYPE_FIND_LIKELY);
|
||||
TYPE_FIND_REGISTER_START_WITH_DEFINE (avs, "video/x-avs",
|
||||
GST_RANK_SECONDARY, NULL, "wW\x10\x00", 4, GST_TYPE_FIND_LIKELY);
|
||||
|
|
Loading…
Reference in a new issue