static void libschroedinger_handle_first_access_unit(AVCodecContext *avctx) { SchroDecoderParams *p_schro_params = avctx->priv_data; SchroDecoder *decoder = p_schro_params->decoder; p_schro_params->format = schro_decoder_get_video_format(decoder); /* Tell FFmpeg about sequence details. */ if (av_image_check_size(p_schro_params->format->width, p_schro_params->format->height, 0, avctx) < 0) { av_log(avctx, AV_LOG_ERROR, "invalid dimensions (%dx%d)\n", p_schro_params->format->width, p_schro_params->format->height); avctx->height = avctx->width = 0; return; } avctx->height = p_schro_params->format->height; avctx->width = p_schro_params->format->width; avctx->pix_fmt = get_chroma_format(p_schro_params->format->chroma_format); if (ff_get_schro_frame_format(p_schro_params->format->chroma_format, &p_schro_params->frame_format) == -1) { av_log(avctx, AV_LOG_ERROR, "This codec currently only supports planar YUV 4:2:0, 4:2:2 " "and 4:4:4 formats.\n"); return; } avctx->framerate.num = p_schro_params->format->frame_rate_numerator; avctx->framerate.den = p_schro_params->format->frame_rate_denominator; }
static void get_format(bgav_stream_t * s) { SchroVideoFormat * format; schroedinger_priv_t* priv; priv = s->decoder_priv; format = schro_decoder_get_video_format(priv->dec); /* Get colormodel */ s->data.video.format.pixelformat = get_pixelformat(format); /* Get size */ s->data.video.format.image_width = format->width; s->data.video.format.image_height = format->height; s->data.video.format.frame_width = format->width; s->data.video.format.frame_height = format->height; #if 0 if((vtrack->stream_cmodel == BC_YUV422P16) || (vtrack->stream_cmodel == BC_YUV444P16)) { } else codec->dec_copy_frame = copy_frame_8; #endif priv->frame_format = get_frame_format(format); /* Get interlace mode */ if(format->interlaced) { if(format->top_field_first) s->data.video.format.interlace_mode = GAVL_INTERLACE_TOP_FIRST; else s->data.video.format.interlace_mode = GAVL_INTERLACE_BOTTOM_FIRST; } else s->data.video.format.interlace_mode = GAVL_INTERLACE_NONE; /* Get pixel aspect */ s->data.video.format.pixel_width = format->aspect_ratio_numerator; s->data.video.format.pixel_height = format->aspect_ratio_denominator; /* Get frame rate */ if(!s->data.video.format.timescale) { s->data.video.format.timescale = format->frame_rate_numerator; s->data.video.format.frame_duration = format->frame_rate_denominator;; } free(format); }
static void handle_first_access_unit (GstSchroDec *schro_dec) { SchroVideoFormat *format; GstCaps *caps; format = schro_decoder_get_video_format (schro_dec->decoder); schro_dec->width = format->width; schro_dec->height = format->height; switch(format->chroma_format) { case 0: schro_dec->fourcc = GST_MAKE_FOURCC('A','Y','U','V'); break; case 1: schro_dec->fourcc = GST_MAKE_FOURCC('Y','U','Y','2'); break; case 2: schro_dec->fourcc = GST_MAKE_FOURCC('I','4','2','0'); break; default: g_assert_not_reached(); break; } caps = gst_caps_new_simple ("video/x-raw-yuv", "format", GST_TYPE_FOURCC, schro_dec->fourcc, "width", G_TYPE_INT, format->width, "height", G_TYPE_INT, format->height, "framerate", GST_TYPE_FRACTION, format->frame_rate_numerator, format->frame_rate_denominator, "pixel-aspect-ratio", GST_TYPE_FRACTION, format->aspect_ratio_numerator, format->aspect_ratio_denominator, NULL); GST_DEBUG("setting caps %" GST_PTR_FORMAT, caps); gst_pad_set_caps (schro_dec->srcpad, caps); schro_dec->fps_n = format->frame_rate_numerator; schro_dec->fps_d = format->frame_rate_denominator; schro_dec->bytes_per_picture = (format->width * format->height * 3) / 4; if (!GST_CLOCK_TIME_IS_VALID(schro_dec->timestamp_offset)) { schro_dec->timestamp_offset = gst_util_uint64_scale ( granulepos_to_frame (schro_dec->granulepos_offset), schro_dec->fps_d * GST_SECOND, schro_dec->fps_n); } gst_caps_unref (caps); free (format); gst_schrodec_send_tags (schro_dec); schro_dec->have_access_unit = TRUE; }
static void libschroedinger_handle_first_access_unit(AVCodecContext *avccontext) { FfmpegSchroDecoderParams *p_schro_params = avccontext->priv_data; SchroDecoder *decoder = p_schro_params->decoder; p_schro_params->format = schro_decoder_get_video_format (decoder); /* Tell FFmpeg about sequence details. */ if(avcodec_check_dimensions(avccontext, p_schro_params->format->width, p_schro_params->format->height) < 0) { av_log(avccontext, AV_LOG_ERROR, "invalid dimensions (%dx%d)\n", p_schro_params->format->width, p_schro_params->format->height); avccontext->height = avccontext->width = 0; return; } avccontext->height = p_schro_params->format->height; avccontext->width = p_schro_params->format->width; avccontext->pix_fmt = GetFfmpegChromaFormat(p_schro_params->format->chroma_format); if (ff_get_schro_frame_format( p_schro_params->format->chroma_format, &p_schro_params->frame_format) == -1) { av_log (avccontext, AV_LOG_ERROR, "This codec currently only supports planar YUV 4:2:0, 4:2:2 " "and 4:4:4 formats.\n"); return; } avccontext->time_base.den = p_schro_params->format->frame_rate_numerator; avccontext->time_base.num = p_schro_params->format->frame_rate_denominator; if (p_schro_params->dec_pic.data[0] == NULL) { avpicture_alloc(&p_schro_params->dec_pic, avccontext->pix_fmt, avccontext->width, avccontext->height); } }
void decode (FILE *file) { SchroDecoder *decoder; SchroBuffer *buffer; SchroVideoFormat *format = NULL; SchroFrame *frame; int picture_number; int go; int it; int eos = FALSE; void *packet; int size; int ret; int parse_code; decoder = schro_decoder_new(); schro_decoder_set_picture_order (decoder, SCHRO_DECODER_PICTURE_ORDER_CODED); while(!eos) { ret = parse_packet (file, &packet, &size); if (!ret) { exit(1); } if (size == 0) { schro_decoder_push_end_of_stream (decoder); } else { parse_code = ((uint8_t *)packet)[4]; buffer = schro_buffer_new_with_data (packet, size); buffer->free = buffer_free; buffer->priv = packet; printf("pushing 0x%02x size %d\n", parse_code, size); if (SCHRO_PARSE_CODE_IS_PICTURE (parse_code)) { frame = schro_frame_new_and_alloc (NULL, schro_params_get_frame_format(8, format->chroma_format), format->width, format->height); schro_decoder_add_output_picture (decoder, frame); } it = schro_decoder_push (decoder, buffer); if (it == SCHRO_DECODER_FIRST_ACCESS_UNIT) { format = schro_decoder_get_video_format (decoder); } if (!SCHRO_PARSE_CODE_IS_PICTURE (parse_code)) { continue; } } go = 1; while (go) { it = schro_decoder_wait (decoder); switch (it) { case SCHRO_DECODER_NEED_BITS: go = 0; break; case SCHRO_DECODER_NEED_FRAME: frame = schro_frame_new_and_alloc (NULL, schro_params_get_frame_format(8, format->chroma_format), format->width, format->height); schro_decoder_add_output_picture (decoder, frame); break; case SCHRO_DECODER_OK: picture_number = schro_decoder_get_picture_number (decoder); frame = schro_decoder_pull (decoder); printf("got frame %p, picture number %d\n", frame, picture_number); if (frame) { schro_frame_unref (frame); } go = 0; break; case SCHRO_DECODER_EOS: printf("got eos\n"); eos = TRUE; go = 0; break; case SCHRO_DECODER_STALLED: printf("stall\n"); go = 0; break; case SCHRO_DECODER_ERROR: exit(0); break; } } } printf("freeing decoder\n"); schro_decoder_free (decoder); free(format); }
static bool RunTest(int bit_depth) { bool result = true; const int seq_len = 5; const int width = 100; const int height = 10; int luma_min = 16; int luma_max = 235; int chroma_zero = 128; schro_init(); // set up encoder SchroEncoder *encoder = schro_encoder_new(); schro_encoder_setting_set_double(encoder, "gop_structure", SCHRO_ENCODER_GOP_INTRA_ONLY); schro_encoder_setting_set_double(encoder, "rate_control", SCHRO_ENCODER_RATE_CONTROL_LOSSLESS); //schro_encoder_setting_set_double(encoder, "force_profile", SCHRO_ENCODER_PROFILE_VC2_SIMPLE); //schro_encoder_setting_set_double(encoder, "queue_depth", seq_len); //assert(seq_len <= SCHRO_LIMIT_FRAME_QUEUE_LENGTH); SchroVideoFormat *format = schro_encoder_get_video_format(encoder); if(format) { format->width = width; format->height = height; format->clean_width = format->width; format->clean_height = format->height; format->left_offset = 0; format->top_offset = 0; format->chroma_format = SCHRO_CHROMA_444; const SchroSignalRange range = (bit_depth == 12 ? SCHRO_SIGNAL_RANGE_12BIT_VIDEO : bit_depth == 10 ? SCHRO_SIGNAL_RANGE_10BIT_VIDEO : SCHRO_SIGNAL_RANGE_8BIT_VIDEO); schro_video_format_set_std_signal_range(format, range); luma_min = format->luma_offset; luma_max = format->luma_offset + format->luma_excursion; chroma_zero = format->chroma_offset; format->colour_primaries = SCHRO_COLOUR_PRIMARY_HDTV; format->colour_matrix = SCHRO_COLOUR_MATRIX_HDTV; format->transfer_function = SCHRO_TRANSFER_CHAR_TV_GAMMA; format->interlaced = false; format->frame_rate_numerator = 24; format->frame_rate_denominator = 1; format->aspect_ratio_numerator = 1; format->aspect_ratio_denominator = 1; schro_encoder_set_video_format(encoder, format); free(format); } else return false; schro_encoder_start(encoder); // create frame SchroFrame *start_frame = schro_frame_new_and_alloc(NULL, SCHRO_FRAME_FORMAT_U8_444, width, height); FillFrame<unsigned char>(start_frame, 16, 235, 128); const SchroFrameFormat schro_format = (bit_depth > 8 ? SCHRO_FRAME_FORMAT_S16_444 : SCHRO_FRAME_FORMAT_U8_444); SchroFrame *original_frame = schro_frame_new_and_alloc(NULL, schro_format, width, height); schro_frame_convert(original_frame, start_frame); SchroDecoder *decoder = schro_decoder_new(); // push frames to encoder for(int t = 0; t < seq_len; t++) { SchroFrame *new_frame = schro_frame_dup(original_frame); schro_encoder_push_frame(encoder, new_frame); } // pull packets out of encoder, pass to decoder int packets_out = 0; while(packets_out < seq_len) { SchroStateEnum encoder_state = schro_encoder_wait(encoder); if(encoder_state == SCHRO_STATE_HAVE_BUFFER || encoder_state == SCHRO_STATE_END_OF_STREAM) { int n_decodable_frames = -1; SchroBuffer *buffer = schro_encoder_pull(encoder, &n_decodable_frames); if(buffer) { const int parse_code = buffer->data[4]; if(SCHRO_PARSE_CODE_IS_SEQ_HEADER(parse_code) || SCHRO_PARSE_CODE_IS_AUXILIARY_DATA(parse_code) || SCHRO_PARSE_CODE_IS_PICTURE(parse_code)) { schro_decoder_push(decoder, buffer); //schro_buffer_unref(buffer); if(SCHRO_PARSE_CODE_IS_PICTURE(parse_code)) { packets_out++; } } } } else { assert(encoder_state == SCHRO_STATE_NEED_FRAME); assert(encoder_state != SCHRO_STATE_AGAIN); // yeah, redundant schro_encoder_end_of_stream(encoder); } } // pull frames out of decoder int frames_out = 0; while(frames_out < seq_len) { int decoder_state = schro_decoder_wait(decoder); if(decoder_state == SCHRO_DECODER_FIRST_ACCESS_UNIT) { SchroVideoFormat *format = schro_decoder_get_video_format(decoder); if(format) { assert(format->width == width); assert(format->height == height); assert(format->chroma_format == SCHRO_CHROMA_444); assert(format->luma_offset == luma_min); assert(format->luma_offset + format->luma_excursion == luma_max); assert(format->chroma_offset = chroma_zero); free(format); } } else if(decoder_state == SCHRO_DECODER_NEED_BITS) { schro_decoder_push_end_of_stream(decoder); } else if(decoder_state == SCHRO_DECODER_NEED_FRAME) { SchroFrame *decoder_frame = schro_frame_new_and_alloc(NULL, schro_format, width, height); schro_decoder_add_output_picture(decoder, decoder_frame); } else if(decoder_state == SCHRO_DECODER_OK || decoder_state == SCHRO_DECODER_EOS) { SchroFrame *decoder_frame = schro_decoder_pull(decoder); if(decoder_frame) { frames_out++; bool match = CompareFrames(decoder_frame, original_frame); //std::cout << (match ? "Match!" : "No Match!") << " " << std::endl; if(!match) { // output doesn't match input, so print the values of the // first line of the first component to see what went in and out PrintFirstLine(original_frame); std::cout << "==========" << std::endl; PrintFirstLine(decoder_frame); std::cout << "==========" << std::endl; result = false; } schro_frame_unref(decoder_frame); } } } schro_frame_unref(original_frame); schro_frame_unref(start_frame); schro_decoder_free(decoder); schro_encoder_free(encoder); return result; }
void decode (FILE *file) { SchroDecoder *decoder; SchroBuffer *buffer; SchroVideoFormat *format = NULL; SchroFrame *frame; int go; int it; int eos = FALSE; void *packet; int size; int ret; decoder = schro_decoder_new(); while(!eos) { ret = parse_packet (file, &packet, &size); if (!ret) { exit(1); } if (size == 0) { schro_decoder_push_end_of_stream (decoder); } else { buffer = schro_buffer_new_with_data (packet, size); buffer->free = buffer_free; buffer->priv = packet; it = schro_decoder_push (decoder, buffer); if (it == SCHRO_DECODER_FIRST_ACCESS_UNIT) { format = schro_decoder_get_video_format (decoder); } } go = 1; while (go) { it = schro_decoder_wait (decoder); switch (it) { case SCHRO_DECODER_NEED_BITS: go = 0; break; case SCHRO_DECODER_NEED_FRAME: frame = schro_frame_new_and_alloc (NULL, schro_params_get_frame_format(8, format->chroma_format), format->width, format->height); schro_decoder_add_output_picture (decoder, frame); break; case SCHRO_DECODER_OK: frame = schro_decoder_pull (decoder); //printf("got frame %p\n", frame); if (frame) { //printf("picture number %d\n", // schro_decoder_get_picture_number (decoder) - 1); schro_frame_unref (frame); } break; case SCHRO_DECODER_EOS: printf("got eos\n"); eos = TRUE; go = 0; break; case SCHRO_DECODER_ERROR: exit(0); break; } } } printf("freeing decoder\n"); schro_decoder_free (decoder); free(format); }