static gboolean sink_event(GstPad *pad, GstEvent *event) { struct obj *self; gboolean ret = TRUE; self = (struct obj *)(gst_pad_get_parent(pad)); GST_DEBUG_OBJECT (self, "sink event %"GST_PTR_FORMAT, event); switch (GST_EVENT_TYPE(event)) { case GST_EVENT_EOS: get_delayed(self); break; case GST_EVENT_FLUSH_START: g_mutex_lock(&self->mutex); avcodec_flush_buffers(self->av_ctx); g_mutex_unlock(&self->mutex); break; default: break; } ret = gst_pad_push_event(self->srcpad, event); gst_object_unref(self); GST_DEBUG_OBJECT (self, "sink event returning %d", ret); return ret; }
static gboolean sink_event(GstPad *pad, GstEvent *event) { struct obj *self; gboolean ret = TRUE; self = (struct obj *)(gst_pad_get_parent(pad)); if (GST_EVENT_TYPE(event) == GST_EVENT_EOS) get_delayed(self); ret = gst_pad_push_event(self->srcpad, event); gst_object_unref(self); return ret; }
static gboolean sink_setcaps(GstPad *pad, GstCaps *caps) { struct obj *self; GstStructure *in_struc; const char *name; int codec_id; const GValue *codec_data; GstBuffer *buf; AVCodecContext *ctx; self = (struct obj *)((GstObject *)pad)->parent; ctx = self->av_ctx; if (ctx) { /* reset */ get_delayed(self); gst_av_codec_close(ctx); av_freep(&ctx->extradata); av_freep(&self->av_ctx); self->initialized = false; } in_struc = gst_caps_get_structure(caps, 0); name = gst_structure_get_name(in_struc); if (strcmp(name, "video/x-h263") == 0) codec_id = CODEC_ID_H263; else if (strcmp(name, "video/x-h264") == 0) codec_id = CODEC_ID_H264; else if (strcmp(name, "video/mpeg") == 0) { int version; gst_structure_get_int(in_struc, "mpegversion", &version); switch (version) { case 4: codec_id = CODEC_ID_MPEG4; break; case 2: codec_id = CODEC_ID_MPEG2VIDEO; break; case 1: codec_id = CODEC_ID_MPEG1VIDEO; break; default: codec_id = CODEC_ID_NONE; break; } } else if (strcmp(name, "video/x-divx") == 0) { int version; gst_structure_get_int(in_struc, "divxversion", &version); switch (version) { case 5: case 4: codec_id = CODEC_ID_MPEG4; break; case 3: codec_id = CODEC_ID_MSMPEG4V3; break; default: codec_id = CODEC_ID_NONE; break; } } else if (strcmp(name, "video/x-xvid") == 0) codec_id = CODEC_ID_MPEG4; else if (strcmp(name, "video/x-3ivx") == 0) codec_id = CODEC_ID_MPEG4; else if (strcmp(name, "video/x-vp8") == 0) codec_id = CODEC_ID_VP8; else if (strcmp(name, "video/x-theora") == 0) codec_id = CODEC_ID_THEORA; else if (strcmp(name, "video/x-wmv") == 0) { int version; gst_structure_get_int(in_struc, "wmvversion", &version); switch (version) { case 3: { guint32 fourcc; codec_id = CODEC_ID_WMV3; if (gst_structure_get_fourcc(in_struc, "fourcc", &fourcc) || gst_structure_get_fourcc(in_struc, "format", &fourcc)) { if (fourcc == GST_MAKE_FOURCC('W', 'V', 'C', '1')) codec_id = CODEC_ID_VC1; } break; } case 2: codec_id = CODEC_ID_WMV2; break; case 1: codec_id = CODEC_ID_WMV1; break; default: codec_id = CODEC_ID_NONE; break; } } else codec_id = CODEC_ID_NONE; self->codec = avcodec_find_decoder(codec_id); if (!self->codec) return false; switch (codec_id) { case CODEC_ID_H263: self->parse_func = gst_av_h263_parse; break; case CODEC_ID_H264: self->parse_func = gst_av_h264_parse; break; case CODEC_ID_MPEG4: self->parse_func = gst_av_mpeg4_parse; break; } self->av_ctx = ctx = avcodec_alloc_context3(self->codec); ctx->get_buffer = get_buffer; ctx->release_buffer = release_buffer; ctx->reget_buffer = reget_buffer; ctx->opaque = self; ctx->flags |= CODEC_FLAG_EMU_EDGE; gst_structure_get_int(in_struc, "width", &ctx->width); gst_structure_get_int(in_struc, "height", &ctx->height); gst_structure_get_fraction(in_struc, "pixel-aspect-ratio", &ctx->sample_aspect_ratio.num, &ctx->sample_aspect_ratio.den); gst_structure_get_fraction(in_struc, "framerate", &ctx->time_base.den, &ctx->time_base.num); /* bug in xvimagesink? */ if (!ctx->time_base.num) ctx->time_base = (AVRational){ 1, 0 }; if (codec_id == CODEC_ID_THEORA) { get_theora_extradata(ctx, in_struc); goto next; } codec_data = gst_structure_get_value(in_struc, "codec_data"); if (!codec_data) goto next; buf = gst_value_get_buffer(codec_data); if (!buf) goto next; ctx->extradata = av_malloc(buf->size + FF_INPUT_BUFFER_PADDING_SIZE); memcpy(ctx->extradata, buf->data, buf->size); memset(ctx->extradata + buf->size, 0, FF_INPUT_BUFFER_PADDING_SIZE); ctx->extradata_size = buf->size; if (self->parse_func) self->parse_func(self, buf); next: return true; }