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; }
static gavl_source_status_t get_data(bgav_stream_t * s, SchroBuffer ** ret_p) { gavl_source_status_t st; schroedinger_priv_t* priv; SchroBuffer * ret; int size; uint8_t * data; priv = s->decoder_priv; if(priv->eof) return GAVL_SOURCE_EOF; if(priv->buffer_size < 13) { if(priv->p) { bgav_stream_done_packet_read(s, priv->p); priv->p = NULL; } if(!priv->header_sent) { priv->buffer_size = s->ext_size; priv->buffer_ptr = s->ext_data; priv->header_sent = 1; } else { while(1) { if((st = bgav_stream_get_packet_read(s, &priv->p)) != GAVL_SOURCE_OK) { if(st == GAVL_SOURCE_EOF) { schro_decoder_push_end_of_stream(priv->dec); priv->eof = 1; } return st; } if(!(priv->p->flags & PACKET_FLAG_SKIP)) break; bgav_stream_done_packet_read(s, priv->p); } priv->buffer_size = priv->p->data_size; priv->buffer_ptr = priv->p->data; } } // fprintf(stderr, "Got packet\n"); // bgav_packet_dump(priv->p); // gavl_hexdump(priv->p->data, 16, 16); size = next_startcode(priv->buffer_ptr, priv->buffer_size); if(SCHRO_PARSE_CODE_IS_PICTURE(priv->buffer_ptr[4])) { if(priv->p->pts != priv->last_pts) { uint32_t pic_num; pic_num = BGAV_PTR_2_32BE(priv->buffer_ptr + 13); // fprintf(stderr, "Got picture %d\n", pic_num); bgav_pts_cache_push(&priv->pc, priv->p, NULL, NULL); priv->last_pts = priv->p->pts; } // codec->dec_delay++; // fprintf(stderr, "** Delay++: %d\n", codec->dec_delay); } else if(SCHRO_PARSE_CODE_IS_SEQ_HEADER(priv->buffer_ptr[4])) { // fprintf(stderr, "Got sequence\n"); } data = malloc(size); memcpy(data, priv->buffer_ptr, size); // fprintf(stderr, "Buffer %d\n", size); // lqt_hexdump(data, 128 > size ? size : 128, 16); ret = schro_buffer_new_with_data(data, size); ret->free = buffer_free; ret->priv = data; priv->buffer_size -= size; priv->buffer_ptr += size; *ret_p = ret; return GAVL_SOURCE_OK; }
int main (int argc, char *argv[]) { FILE *file; int ret; DiracSequenceHeader header = {0}; int size; unsigned char *packet; int n; int i; if (argc < 2) { fprintf(stderr, "parse_header infile.drc\n"); return 1; } file = fopen (argv[1], "r"); if (file == NULL) { printf("cannot open %s for reading: %s\n", argv[1], strerror(errno)); return 1; } n = fread (data, 1, 4096, file); if (n < 13) { printf("file too short\n"); exit(1); } for(i=0;i<=n - 13;i++){ packet = data + i; if (packet[0] == 'B' && packet[1] == 'B' && packet[2] == 'C' && packet[3] == 'D') { size = (packet[5]<<24) | (packet[6]<<16) | (packet[7]<<8) | (packet[8]); if (size == 0) { size = 13; } if (i + size > n) { continue; } if (SCHRO_PARSE_CODE_IS_SEQ_HEADER(packet[4])) { ret = dirac_sequence_header_parse (&header, packet + 13, size - 13); if (!ret) { printf("bad header\n"); exit(1); } #define PRINT(ack) printf( #ack ": %d\n", header. ack ); PRINT(major_version); PRINT(minor_version); PRINT(profile); PRINT(level); PRINT(index); PRINT(width); PRINT(height); PRINT(chroma_format); PRINT(interlaced); PRINT(top_field_first); PRINT(frame_rate_numerator); PRINT(frame_rate_denominator); PRINT(aspect_ratio_numerator); PRINT(aspect_ratio_denominator); PRINT(clean_width); PRINT(clean_height); PRINT(left_offset); PRINT(top_offset); PRINT(luma_offset); PRINT(luma_excursion); PRINT(chroma_offset); PRINT(chroma_excursion); PRINT(colour_primaries); PRINT(colour_matrix); PRINT(transfer_function); PRINT(interlaced_coding); return 0; } } } return 0; }