{C_FLAGS (VP8_DEBLOCK), "Deblock", "deblock"},
{C_FLAGS (VP8_DEMACROBLOCK), "Demacroblock", "demacroblock"},
{C_FLAGS (VP8_ADDNOISE), "Add noise", "addnoise"},
+#ifndef HAVE_VPX_1_8
+ {C_FLAGS (VP8_DEBUG_TXT_FRAME_INFO),
+ "Print frame information",
+ "visualize-frame-info"},
+ {C_FLAGS (VP8_DEBUG_TXT_MBLK_MODES),
+ "Show macroblock mode selection overlaid on image",
+ "visualize-macroblock-modes"},
+ {C_FLAGS (VP8_DEBUG_TXT_DC_DIFF),
+ "Show dc diff for each macro block overlaid on image",
+ "visualize-dc-diff"},
+ {C_FLAGS (VP8_DEBUG_TXT_RATE_INFO),
+ "Print video rate info",
+ "visualize-rate-info"},
+#endif
{C_FLAGS (VP8_MFQE), "Multi-frame quality enhancement", "mfqe"},
{0, NULL, NULL}
};
gst_event_new_tag (list));
}
-#ifdef HAVE_VPX_1_4
struct Frame
{
GstMapInfo info;
vpx_codec_frame_buffer_t * fb)
{
GstVPXDec *dec = priv;
- GstBuffer *buffer;
+ GstBuffer *buffer = NULL;
struct Frame *frame;
GstFlowReturn ret;
{
struct Frame *frame = fb->priv;
+ /* We're sometimes called without a frame */
+ if (!frame)
+ return 0;
+
GST_TRACE_OBJECT (priv, "Release buffer %p", frame->buffer);
- g_assert (frame);
gst_buffer_unmap (frame->buffer, &frame->info);
gst_buffer_unref (frame->buffer);
g_free (frame);
+ fb->priv = NULL;
return 0;
}
-#endif
static void
gst_vpx_dec_image_to_buffer (GstVPXDec * dec, const vpx_image_t * img,
if (status != VPX_CODEC_OK) {
GST_WARNING_OBJECT (dec, "VPX preprocessing error: %s",
gst_vpx_error_name (status));
- gst_video_decoder_drop_frame (GST_VIDEO_DECODER (dec), frame);
return GST_FLOW_CUSTOM_SUCCESS_1;
}
if (!stream_info.is_kf) {
GST_WARNING_OBJECT (dec, "No keyframe, skipping");
- gst_video_decoder_drop_frame (GST_VIDEO_DECODER (dec), frame);
+ return GST_FLOW_CUSTOM_SUCCESS_1;
+ }
+ if (stream_info.w == 0 || stream_info.h == 0) {
+ /* For VP8 it's possible to signal width or height to be 0, but it does
+ * not make sense to do so. For VP9 it's impossible. Hence, we most likely
+ * have a corrupt stream if width or height is 0. */
+ GST_INFO_OBJECT (dec, "Invalid resolution %d x %d", stream_info.w,
+ stream_info.h);
return GST_FLOW_CUSTOM_SUCCESS_1;
}
cfg.w = stream_info.w;
cfg.h = stream_info.h;
- cfg.threads = dec->threads;
+
+ if (dec->threads > 0)
+ cfg.threads = dec->threads;
+ else
+ cfg.threads = g_get_num_processors ();
caps = vpx_codec_get_caps (vpxclass->codec_algo);
gst_vpx_error_name (status));
}
}
-#ifdef HAVE_VPX_1_4
vpx_codec_set_frame_buffer_functions (&dec->decoder,
gst_vpx_dec_get_buffer_cb, gst_vpx_dec_release_buffer_cb, dec);
-#endif
dec->decoder_inited = TRUE;
if (!dec->decoder_inited) {
ret = vpxclass->open_codec (dec, frame);
- if (ret == GST_FLOW_CUSTOM_SUCCESS_1)
+ if (ret == GST_FLOW_CUSTOM_SUCCESS_1) {
+ gst_video_decoder_drop_frame (decoder, frame);
return GST_FLOW_OK;
- else if (ret != GST_FLOW_OK)
+ } else if (ret != GST_FLOW_OK) {
+ gst_video_codec_frame_unref (frame);
return ret;
+ }
}
deadline = gst_video_decoder_get_max_decode_time (decoder, frame);
if (!gst_buffer_map (frame->input_buffer, &minfo, GST_MAP_READ)) {
GST_ERROR_OBJECT (dec, "Failed to map input buffer");
+ gst_video_codec_frame_unref (frame);
return GST_FLOW_ERROR;
}
if (status) {
GST_VIDEO_DECODER_ERROR (decoder, 1, LIBRARY, ENCODE,
("Failed to decode frame"), ("%s", gst_vpx_error_name (status)), ret);
+ gst_video_codec_frame_unref (frame);
return ret;
}
GST_ELEMENT_ERROR (decoder, LIBRARY, ENCODE,
("Failed to decode frame"), ("Unsupported color format %d",
img->fmt));
+ gst_video_codec_frame_unref (frame);
return GST_FLOW_ERROR;
}
gst_video_decoder_drop_frame (decoder, frame);
} else {
gst_vpx_dec_handle_resolution_change (dec, img, fmt);
-#ifdef HAVE_VPX_1_4
if (img->fb_priv && dec->have_video_meta) {
frame->output_buffer = gst_vpx_dec_prepare_image (dec, img);
ret = gst_video_decoder_finish_frame (decoder, frame);
- } else
-#endif
- {
+ } else {
ret = gst_video_decoder_allocate_output_frame (decoder, frame);
if (ret == GST_FLOW_OK) {