static av_cold int libschroedinger_decode_init(AVCodecContext *avctx) { SchroDecoderParams *p_schro_params = avctx->priv_data; /* First of all, initialize our supporting libraries. */ schro_init(); schro_debug_set_level(avctx->debug); p_schro_params->decoder = schro_decoder_new(); schro_decoder_set_skip_ratio(p_schro_params->decoder, 1); if (!p_schro_params->decoder) return -1; /* Initialize the decoded frame queue. */ ff_schro_queue_init(&p_schro_params->dec_frame_queue); return 0; }
static GstFlowReturn gst_schro_dec_process_buffer (GstSchroDec *schro_dec, SchroBuffer *input_buffer) { GstFlowReturn ret = GST_FLOW_OK; SchroFrame *frame; int size; int earliest_frame; GstBuffer *outbuf; int go = 1; if (input_buffer) { ret = schro_decoder_push (schro_dec->decoder, input_buffer); if (ret == SCHRO_DECODER_FIRST_ACCESS_UNIT) { handle_first_access_unit (schro_dec); } } else { ret = schro_decoder_push_end_of_stream (schro_dec->decoder); } if (schro_dec->have_access_unit) { earliest_frame = gst_util_uint64_scale ( schro_dec->earliest_time - schro_dec->segment.start, schro_dec->fps_n, schro_dec->fps_d * GST_SECOND); GST_DEBUG("earliest frame %d", earliest_frame); schro_decoder_set_earliest_frame (schro_dec->decoder, earliest_frame); schro_decoder_set_skip_ratio (schro_dec->decoder, 1/schro_dec->proportion); } while (go) { int it; it = schro_decoder_wait (schro_dec->decoder); switch (it) { case SCHRO_DECODER_FIRST_ACCESS_UNIT: handle_first_access_unit (schro_dec); break; case SCHRO_DECODER_NEED_BITS: go = 0; break; case SCHRO_DECODER_NEED_FRAME: size = get_buffer_size (schro_dec); ret = gst_pad_alloc_buffer_and_set_caps (schro_dec->srcpad, GST_BUFFER_OFFSET_NONE, size, GST_PAD_CAPS (schro_dec->srcpad), &outbuf); if (ret != GST_FLOW_OK) { GST_DEBUG("could not allocate buffer for pad"); return ret; } frame = gst_schro_wrap_frame (schro_dec, outbuf); schro_decoder_add_output_picture (schro_dec->decoder, frame); break; case SCHRO_DECODER_OK: frame = schro_decoder_pull (schro_dec->decoder); if (frame) { if (frame->priv) { outbuf = frame->priv; if (schro_dec->discont) { GST_DEBUG("discont timestamp %" G_GINT64_FORMAT, GST_BUFFER_TIMESTAMP(outbuf)); GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_DISCONT); schro_dec->discont = FALSE; } GST_BUFFER_TIMESTAMP(outbuf) = gst_util_uint64_scale ( schro_dec->n_frames, schro_dec->fps_d * GST_SECOND, schro_dec->fps_n) + schro_dec->timestamp_offset; GST_BUFFER_DURATION(outbuf) = gst_util_uint64_scale_int (GST_SECOND, schro_dec->fps_d, schro_dec->fps_n); gst_buffer_ref(outbuf); ret = gst_pad_push (schro_dec->srcpad, outbuf); if (ret != GST_FLOW_OK) return ret; } else { GST_DEBUG("skipped frame %d", schro_dec->n_frames); } schro_dec->n_frames++; schro_frame_unref (frame); } break; case SCHRO_DECODER_EOS: go = FALSE; break; case SCHRO_DECODER_ERROR: go = FALSE; GST_ERROR ("codec error"); ret = GST_FLOW_ERROR; break; } } return ret; }