static GstFlowReturn pad_chain(GstPad *pad, GstBuffer *buf) { struct obj *self; GstFlowReturn ret = GST_FLOW_OK; AVCodecContext *ctx; AVFrame *frame; int got_pic; AVPacket pkt; int read; self = (struct obj *)((GstObject *)pad)->parent; ctx = self->av_ctx; if (G_UNLIKELY(!self->initialized)) { GstCaps *new_caps; GstStructure *struc; self->initialized = true; if (gst_av_codec_open(ctx, self->codec) < 0) { ret = GST_FLOW_ERROR; goto leave; } if (self->parse_func) self->parse_func(self, buf); new_caps = gst_caps_new_empty(); struc = gst_structure_new("video/x-raw-yuv", "width", G_TYPE_INT, ctx->width, "height", G_TYPE_INT, ctx->height, "format", GST_TYPE_FOURCC, GST_MAKE_FOURCC('I','4','2','0'), NULL); if (ctx->time_base.num) gst_structure_set(struc, "framerate", GST_TYPE_FRACTION, ctx->time_base.den, ctx->time_base.num, NULL); if (ctx->sample_aspect_ratio.num) gst_structure_set(struc, "pixel-aspect-ratio", GST_TYPE_FRACTION, ctx->sample_aspect_ratio.num, ctx->sample_aspect_ratio.den, NULL); gst_caps_append_structure(new_caps, struc); GST_INFO_OBJECT(self, "caps are: %" GST_PTR_FORMAT, new_caps); gst_pad_set_caps(self->srcpad, new_caps); gst_caps_unref(new_caps); } av_init_packet(&pkt); pkt.data = buf->data; pkt.size = buf->size; frame = avcodec_alloc_frame(); read = avcodec_decode_video2(ctx, frame, &got_pic, &pkt); if (read < 0) { GST_WARNING_OBJECT(self, "error: %i", read); goto leave; } if (got_pic) { GstBuffer *out_buf; out_buf = convert_frame(self, frame); out_buf->timestamp = buf->timestamp; out_buf->duration = buf->duration; ret = gst_pad_push(self->srcpad, out_buf); } leave: gst_buffer_unref(buf); return ret; }
static GstFlowReturn pad_chain(GstPad *pad, GstBuffer *buf) { struct obj *self; GstFlowReturn ret = GST_FLOW_OK; AVCodecContext *ctx; AVFrame *frame = NULL; int got_pic; AVPacket pkt; int read; self = (struct obj *)((GstObject *)pad)->parent; GST_DEBUG_OBJECT (self, "pad chain"); ctx = self->av_ctx; if (G_UNLIKELY(!self->initialized)) { GstCaps *new_caps; GstStructure *struc; self->initialized = true; if (gst_av_codec_open(ctx, self->codec) < 0) { ret = GST_FLOW_ERROR; goto leave; } if (self->parse_func) self->parse_func(self, buf); new_caps = gst_caps_new_empty(); struc = gst_structure_new("video/x-raw-yuv", "width", G_TYPE_INT, ctx->width, "height", G_TYPE_INT, ctx->height, "format", GST_TYPE_FOURCC, GST_MAKE_FOURCC('I','4','2','0'), NULL); if (ctx->time_base.num) gst_structure_set(struc, "framerate", GST_TYPE_FRACTION, ctx->time_base.den, ctx->time_base.num * ctx->ticks_per_frame, NULL); if (ctx->sample_aspect_ratio.num) gst_structure_set(struc, "pixel-aspect-ratio", GST_TYPE_FRACTION, ctx->sample_aspect_ratio.num, ctx->sample_aspect_ratio.den, NULL); gst_caps_append_structure(new_caps, struc); GST_INFO_OBJECT(self, "caps are: %" GST_PTR_FORMAT, new_caps); gst_pad_set_caps(self->srcpad, new_caps); gst_caps_unref(new_caps); } av_new_packet(&pkt, buf->size); memcpy(pkt.data, buf->data, buf->size); memset(pkt.data + pkt.size, 0, FF_INPUT_BUFFER_PADDING_SIZE); frame = avcodec_alloc_frame(); pkt.dts = pkt.pts = gstav_timestamp_to_pts(ctx, buf->timestamp); #if LIBAVCODEC_VERSION_MAJOR < 53 ctx->reordered_opaque = pkt.dts; #endif g_mutex_lock(&self->mutex); read = avcodec_decode_video2(ctx, frame, &got_pic, &pkt); av_free_packet(&pkt); if (read < 0) { GST_WARNING_OBJECT(self, "error: %i", read); g_mutex_unlock(&self->mutex); goto leave; } if (got_pic) { GstBuffer *out_buf; out_buf = convert_frame(self, frame); g_mutex_unlock(&self->mutex); ret = gst_pad_push(self->srcpad, out_buf); } else g_mutex_unlock(&self->mutex); leave: av_free(frame); gst_buffer_unref(buf); GST_DEBUG_OBJECT (self, "pad chain returning %s", gst_flow_get_name (ret)); return ret; }