예제 #1
0
static int libschroedinger_encode_frame(AVCodecContext *avccontext, AVPacket *pkt,
                                        const AVFrame *frame, int *got_packet)
{
    int enc_size = 0;
    SchroEncoderParams *p_schro_params = avccontext->priv_data;
    SchroEncoder *encoder = p_schro_params->encoder;
    struct FFSchroEncodedFrame *p_frame_output = NULL;
    int go = 1;
    SchroBuffer *enc_buf;
    int presentation_frame;
    int parse_code;
    int last_frame_in_sequence = 0;
    int pkt_size, ret;

    if (!frame) {
        /* Push end of sequence if not already signalled. */
        if (!p_schro_params->eos_signalled) {
            schro_encoder_end_of_stream(encoder);
            p_schro_params->eos_signalled = 1;
        }
    } else {
        /* Allocate frame data to schro input buffer. */
        SchroFrame *in_frame = libschroedinger_frame_from_data(avccontext,
                                                               frame);
        /* Load next frame. */
        schro_encoder_push_frame(encoder, in_frame);
    }

    if (p_schro_params->eos_pulled)
        go = 0;

    /* Now check to see if we have any output from the encoder. */
    while (go) {
        SchroStateEnum state;
        state = schro_encoder_wait(encoder);
        switch (state) {
        case SCHRO_STATE_HAVE_BUFFER:
        case SCHRO_STATE_END_OF_STREAM:
            enc_buf = schro_encoder_pull(encoder, &presentation_frame);
            assert(enc_buf->length > 0);
            assert(enc_buf->length <= buf_size);
            parse_code = enc_buf->data[4];

            /* All non-frame data is prepended to actual frame data to
             * be able to set the pts correctly. So we don't write data
             * to the frame output queue until we actually have a frame
             */
            p_schro_params->enc_buf = av_realloc(p_schro_params->enc_buf,
                                                 p_schro_params->enc_buf_size + enc_buf->length);

            memcpy(p_schro_params->enc_buf + p_schro_params->enc_buf_size,
                   enc_buf->data, enc_buf->length);
            p_schro_params->enc_buf_size += enc_buf->length;


            if (state == SCHRO_STATE_END_OF_STREAM) {
                p_schro_params->eos_pulled = 1;
                go = 0;
            }

            if (!SCHRO_PARSE_CODE_IS_PICTURE(parse_code)) {
                schro_buffer_unref(enc_buf);
                break;
            }

            /* Create output frame. */
            p_frame_output = av_mallocz(sizeof(FFSchroEncodedFrame));
            /* Set output data. */
            p_frame_output->size     = p_schro_params->enc_buf_size;
            p_frame_output->p_encbuf = p_schro_params->enc_buf;
            if (SCHRO_PARSE_CODE_IS_INTRA(parse_code) &&
                SCHRO_PARSE_CODE_IS_REFERENCE(parse_code))
                p_frame_output->key_frame = 1;

            /* Parse the coded frame number from the bitstream. Bytes 14
             * through 17 represesent the frame number. */
            p_frame_output->frame_num = AV_RB32(enc_buf->data + 13);

            ff_schro_queue_push_back(&p_schro_params->enc_frame_queue,
                                     p_frame_output);
            p_schro_params->enc_buf_size = 0;
            p_schro_params->enc_buf      = NULL;

            schro_buffer_unref(enc_buf);

            break;

        case SCHRO_STATE_NEED_FRAME:
            go = 0;
            break;

        case SCHRO_STATE_AGAIN:
            break;

        default:
            av_log(avccontext, AV_LOG_ERROR, "Unknown Schro Encoder state\n");
            return -1;
        }
    }

    /* Copy 'next' frame in queue. */

    if (p_schro_params->enc_frame_queue.size == 1 &&
        p_schro_params->eos_pulled)
        last_frame_in_sequence = 1;

    p_frame_output = ff_schro_queue_pop(&p_schro_params->enc_frame_queue);

    if (!p_frame_output)
        return 0;

    pkt_size = p_frame_output->size;
    if (last_frame_in_sequence && p_schro_params->enc_buf_size > 0)
        pkt_size += p_schro_params->enc_buf_size;
    if ((ret = ff_alloc_packet(pkt, pkt_size)) < 0) {
        av_log(avccontext, AV_LOG_ERROR, "Error getting output packet of size %d.\n", pkt_size);
        goto error;
    }

    memcpy(pkt->data, p_frame_output->p_encbuf, p_frame_output->size);
    avccontext->coded_frame->key_frame = p_frame_output->key_frame;
    /* Use the frame number of the encoded frame as the pts. It is OK to
     * do so since Dirac is a constant frame rate codec. It expects input
     * to be of constant frame rate. */
    pkt->pts =
    avccontext->coded_frame->pts = p_frame_output->frame_num;
    pkt->dts = p_schro_params->dts++;
    enc_size = p_frame_output->size;

    /* Append the end of sequence information to the last frame in the
     * sequence. */
    if (last_frame_in_sequence && p_schro_params->enc_buf_size > 0) {
        memcpy(pkt->data + enc_size, p_schro_params->enc_buf,
               p_schro_params->enc_buf_size);
        enc_size += p_schro_params->enc_buf_size;
        av_freep(&p_schro_params->enc_buf);
        p_schro_params->enc_buf_size = 0;
    }

    if (p_frame_output->key_frame)
        pkt->flags |= AV_PKT_FLAG_KEY;
    *got_packet = 1;

error:
    /* free frame */
    libschroedinger_free_frame(p_frame_output);
    return ret;
}
예제 #2
0
static int libschroedinger_decode_frame(AVCodecContext *avccontext,
                                        void *data, int *data_size,
                                        AVPacket *avpkt)
{
    const uint8_t *buf = avpkt->data;
    int buf_size = avpkt->size;

    FfmpegSchroDecoderParams *p_schro_params = avccontext->priv_data;
    SchroDecoder *decoder = p_schro_params->decoder;
    SchroVideoFormat *format;
    AVPicture *picture = data;
    SchroBuffer *enc_buf;
    SchroFrame* frame;
    int state;
    int go = 1;
    int outer = 1;
    FfmpegSchroParseUnitContext parse_ctx;

    *data_size = 0;

    FfmpegSchroParseContextInit(&parse_ctx, buf, buf_size);
    if (!buf_size) {
        if (!p_schro_params->eos_signalled) {
            state = schro_decoder_push_end_of_stream(decoder);
            p_schro_params->eos_signalled = 1;
        }
    }

    /* Loop through all the individual parse units in the input buffer */
    do {
        if ((enc_buf = FfmpegFindNextSchroParseUnit(&parse_ctx))) {
            /* Push buffer into decoder. */
            if (SCHRO_PARSE_CODE_IS_PICTURE(enc_buf->data[4]) &&
                SCHRO_PARSE_CODE_NUM_REFS(enc_buf->data[4]) > 0)
                avccontext->has_b_frames = 1;
            state = schro_decoder_push(decoder, enc_buf);
            if (state == SCHRO_DECODER_FIRST_ACCESS_UNIT)
                libschroedinger_handle_first_access_unit(avccontext);
            go = 1;
        } else
            outer = 0;
        format = p_schro_params->format;

        while (go) {
            /* Parse data and process result. */
            state = schro_decoder_wait(decoder);
            switch (state) {
            case SCHRO_DECODER_FIRST_ACCESS_UNIT:
                libschroedinger_handle_first_access_unit(avccontext);
                break;

            case SCHRO_DECODER_NEED_BITS:
                /* Need more input data - stop iterating over what we have. */
                go = 0;
                break;

            case SCHRO_DECODER_NEED_FRAME:
                /* Decoder needs a frame - create one and push it in. */
                frame = ff_create_schro_frame(avccontext,
                                              p_schro_params->frame_format);
                schro_decoder_add_output_picture(decoder, frame);
                break;

            case SCHRO_DECODER_OK:
                /* Pull a frame out of the decoder. */
                frame = schro_decoder_pull(decoder);

                if (frame)
                    ff_dirac_schro_queue_push_back(&p_schro_params->dec_frame_queue,
                                                   frame);
                break;
            case SCHRO_DECODER_EOS:
                go = 0;
                p_schro_params->eos_pulled = 1;
                schro_decoder_reset(decoder);
                outer = 0;
                break;

            case SCHRO_DECODER_ERROR:
                return -1;
                break;
            }
        }
    } while (outer);

    /* Grab next frame to be returned from the top of the queue. */
    frame = ff_dirac_schro_queue_pop(&p_schro_params->dec_frame_queue);

    if (frame) {
        memcpy(p_schro_params->dec_pic.data[0],
               frame->components[0].data,
               frame->components[0].length);

        memcpy(p_schro_params->dec_pic.data[1],
               frame->components[1].data,
               frame->components[1].length);

        memcpy(p_schro_params->dec_pic.data[2],
               frame->components[2].data,
               frame->components[2].length);

        /* Fill picture with current buffer data from Schroedinger. */
        avpicture_fill(picture, p_schro_params->dec_pic.data[0],
                       avccontext->pix_fmt,
                       avccontext->width, avccontext->height);

        *data_size = sizeof(AVPicture);

        /* Now free the frame resources. */
        libschroedinger_decode_frame_free(frame);
    }
    return buf_size;
}
static int libschroedinger_decode_frame(AVCodecContext *avctx,
                                        void *data, int *got_frame,
                                        AVPacket *avpkt)
{
    const uint8_t *buf = avpkt->data;
    int buf_size = avpkt->size;
    int64_t pts  = avpkt->pts;
    SchroTag *tag;

    SchroDecoderParams *p_schro_params = avctx->priv_data;
    SchroDecoder *decoder = p_schro_params->decoder;
    SchroBuffer *enc_buf;
    SchroFrame* frame;
    AVFrame *avframe = data;
    int state;
    int go = 1;
    int outer = 1;
    SchroParseUnitContext parse_ctx;
    LibSchroFrameContext *framewithpts = NULL;

    *got_frame = 0;

    parse_context_init(&parse_ctx, buf, buf_size);
    if (!buf_size) {
        if (!p_schro_params->eos_signalled) {
            state = schro_decoder_push_end_of_stream(decoder);
            p_schro_params->eos_signalled = 1;
        }
    }

    /* Loop through all the individual parse units in the input buffer */
    do {
        if ((enc_buf = find_next_parse_unit(&parse_ctx))) {
            /* Set Schrotag with the pts to be recovered after decoding*/
            enc_buf->tag = schro_tag_new(av_malloc(sizeof(int64_t)), av_free);
            if (!enc_buf->tag->value) {
                av_log(avctx, AV_LOG_ERROR, "Unable to allocate SchroTag\n");
                return AVERROR(ENOMEM);
            }
            AV_WN(64, enc_buf->tag->value, pts);
            /* Push buffer into decoder. */
            if (SCHRO_PARSE_CODE_IS_PICTURE(enc_buf->data[4]) &&
                SCHRO_PARSE_CODE_NUM_REFS(enc_buf->data[4]) > 0)
                avctx->has_b_frames = 1;
            state = schro_decoder_push(decoder, enc_buf);
            if (state == SCHRO_DECODER_FIRST_ACCESS_UNIT)
                libschroedinger_handle_first_access_unit(avctx);
            go = 1;
        } else
            outer = 0;

        while (go) {
            /* Parse data and process result. */
            state = schro_decoder_wait(decoder);
            switch (state) {
            case SCHRO_DECODER_FIRST_ACCESS_UNIT:
                libschroedinger_handle_first_access_unit(avctx);
                break;

            case SCHRO_DECODER_NEED_BITS:
                /* Need more input data - stop iterating over what we have. */
                go = 0;
                break;

            case SCHRO_DECODER_NEED_FRAME:
                /* Decoder needs a frame - create one and push it in. */
                frame = ff_create_schro_frame(avctx,
                                              p_schro_params->frame_format);
                if (!frame)
                    return AVERROR(ENOMEM);
                schro_decoder_add_output_picture(decoder, frame);
                break;

            case SCHRO_DECODER_OK:
                /* Pull a frame out of the decoder. */
                tag   = schro_decoder_get_picture_tag(decoder);
                frame = schro_decoder_pull(decoder);

                if (frame) {
                    /* Add relation between schroframe and pts. */
                    framewithpts = av_malloc(sizeof(LibSchroFrameContext));
                    if (!framewithpts) {
                        av_log(avctx, AV_LOG_ERROR, "Unable to allocate FrameWithPts\n");
                        return AVERROR(ENOMEM);
                    }
                    framewithpts->frame = frame;
                    framewithpts->pts   = AV_RN64(tag->value);
                    ff_schro_queue_push_back(&p_schro_params->dec_frame_queue,
                                             framewithpts);
                }
                break;
            case SCHRO_DECODER_EOS:
                go = 0;
                p_schro_params->eos_pulled = 1;
                schro_decoder_reset(decoder);
                outer = 0;
                break;

            case SCHRO_DECODER_ERROR:
                return -1;
                break;
            }
        }
    } while (outer);

    /* Grab next frame to be returned from the top of the queue. */
    framewithpts = ff_schro_queue_pop(&p_schro_params->dec_frame_queue);

    if (framewithpts && framewithpts->frame) {
        int ret;

        if ((ret = ff_get_buffer(avctx, avframe, 0)) < 0)
            return ret;

        memcpy(avframe->data[0],
               framewithpts->frame->components[0].data,
               framewithpts->frame->components[0].length);

        memcpy(avframe->data[1],
               framewithpts->frame->components[1].data,
               framewithpts->frame->components[1].length);

        memcpy(avframe->data[2],
               framewithpts->frame->components[2].data,
               framewithpts->frame->components[2].length);

        /* Fill frame with current buffer data from Schroedinger. */
        avframe->pkt_pts = framewithpts->pts;
        avframe->linesize[0] = framewithpts->frame->components[0].stride;
        avframe->linesize[1] = framewithpts->frame->components[1].stride;
        avframe->linesize[2] = framewithpts->frame->components[2].stride;

        *got_frame      = 1;

        /* Now free the frame resources. */
        libschroedinger_decode_frame_free(framewithpts->frame);
        av_free(framewithpts);
    } else {
        data       = NULL;
        *got_frame = 0;
    }
    return buf_size;
}
예제 #4
0
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);
}
예제 #5
0
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;
  }
예제 #6
0
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;
}
예제 #7
0
static GstFlowReturn
gst_dirac_parse_handle_frame (GstBaseParse * parse,
                              GstBaseParseFrame * frame, gint * skipsize)
{
    int off;
    guint32 next_header;
    GstMapInfo map;
    guint8 *data;
    gsize size;
    gboolean have_picture = FALSE;
    int offset;
    guint framesize = 0;

    gst_buffer_map (frame->buffer, &map, GST_MAP_READ);
    data = map.data;
    size = map.size;

    if (G_UNLIKELY (size < 13)) {
        *skipsize = 1;
        goto out;
    }

    GST_DEBUG ("%" G_GSIZE_FORMAT ": %02x %02x %02x %02x", size, data[0], data[1],
               data[2], data[3]);

    if (GST_READ_UINT32_BE (data) != 0x42424344) {
        GstByteReader reader;

        gst_byte_reader_init (&reader, data, size);
        off = gst_byte_reader_masked_scan_uint32 (&reader, 0xffffffff,
                0x42424344, 0, size);

        if (off < 0) {
            *skipsize = size - 3;
            goto out;
        }

        GST_LOG_OBJECT (parse, "possible sync at buffer offset %d", off);

        GST_DEBUG ("skipping %d", off);
        *skipsize = off;
        goto out;
    }

    /* have sync, parse chunks */

    offset = 0;
    while (!have_picture) {
        GST_DEBUG ("offset %d:", offset);

        if (offset + 13 >= size) {
            framesize = offset + 13;
            goto out;
        }

        GST_DEBUG ("chunk type %02x", data[offset + 4]);

        if (GST_READ_UINT32_BE (data + offset) != 0x42424344) {
            GST_DEBUG ("bad header");
            *skipsize = 3;
            goto out;
        }

        next_header = GST_READ_UINT32_BE (data + offset + 5);
        GST_DEBUG ("next_header %d", next_header);
        if (next_header == 0)
            next_header = 13;

        if (SCHRO_PARSE_CODE_IS_PICTURE (data[offset + 4])) {
            have_picture = TRUE;
        }

        offset += next_header;
        if (offset >= size) {
            framesize = offset;
            goto out;
        }
    }

    gst_buffer_unmap (frame->buffer, &map);

    framesize = offset;
    GST_DEBUG ("framesize %d", framesize);

    g_assert (framesize <= size);

    if (data[4] == SCHRO_PARSE_CODE_SEQUENCE_HEADER) {
        GstCaps *caps;
        GstDiracParse *diracparse = GST_DIRAC_PARSE (parse);
        DiracSequenceHeader sequence_header;
        int ret;

        ret = dirac_sequence_header_parse (&sequence_header, data + 13, size - 13);
        if (ret) {
            memcpy (&diracparse->sequence_header, &sequence_header,
                    sizeof (sequence_header));
            caps = gst_caps_new_simple ("video/x-dirac",
                                        "width", G_TYPE_INT, sequence_header.width,
                                        "height", G_TYPE_INT, sequence_header.height,
                                        "framerate", GST_TYPE_FRACTION,
                                        sequence_header.frame_rate_numerator,
                                        sequence_header.frame_rate_denominator,
                                        "pixel-aspect-ratio", GST_TYPE_FRACTION,
                                        sequence_header.aspect_ratio_numerator,
                                        sequence_header.aspect_ratio_denominator,
                                        "interlace-mode", G_TYPE_STRING,
                                        sequence_header.interlaced ? "interleaved" : "progressive",
                                        "profile", G_TYPE_STRING, get_profile_name (sequence_header.profile),
                                        "level", G_TYPE_STRING, get_level_name (sequence_header.level), NULL);
            gst_pad_set_caps (GST_BASE_PARSE_SRC_PAD (parse), caps);
            gst_caps_unref (caps);

            gst_base_parse_set_frame_rate (parse,
                                           sequence_header.frame_rate_numerator,
                                           sequence_header.frame_rate_denominator, 0, 0);
        }
    }

    gst_base_parse_set_min_frame_size (parse, 13);

    return gst_base_parse_finish_frame (parse, frame, framesize);

out:
    gst_buffer_unmap (frame->buffer, &map);
    if (framesize)
        gst_base_parse_set_min_frame_size (parse, framesize);
    return GST_FLOW_OK;
}
예제 #8
0
static void
handle_packet (unsigned char *data, int size)
{
  SchroUnpack unpack;
  const char *parse_code;
  int next;
  int prev;

  if (memcmp (data, "BBCD", 4) != 0) {
    printf("non-Dirac packet\n");
    dump_hex (data, MIN(size, 100), "  ");
    return;
  }

  switch (data[4]) {
    case SCHRO_PARSE_CODE_SEQUENCE_HEADER:
      parse_code = "access unit header";
      break;
    case SCHRO_PARSE_CODE_AUXILIARY_DATA:
      parse_code = "auxiliary data";
      break;
    case SCHRO_PARSE_CODE_INTRA_REF:
      parse_code = "intra ref";
      break;
    case SCHRO_PARSE_CODE_INTRA_NON_REF:
      parse_code = "intra non-ref";
      break;
    case SCHRO_PARSE_CODE_INTER_REF_1:
      parse_code = "inter ref 1";
      break;
    case SCHRO_PARSE_CODE_INTER_REF_2:
      parse_code = "inter ref 2";
      break;
    case SCHRO_PARSE_CODE_INTER_NON_REF_1:
      parse_code = "inter non-ref 1";
      break;
    case SCHRO_PARSE_CODE_INTER_NON_REF_2:
      parse_code = "inter non-ref 2";
      break;
    case SCHRO_PARSE_CODE_END_OF_SEQUENCE:
      parse_code = "end of sequence";
      break;
    case SCHRO_PARSE_CODE_LD_INTRA_REF:
      parse_code = "low-delay intra ref";
      break;
    case SCHRO_PARSE_CODE_LD_INTRA_NON_REF:
      parse_code = "low-delay intra non-ref";
      break;
    case SCHRO_PARSE_CODE_INTRA_REF_NOARITH:
      parse_code = "intra ref noarith";
      break;
    case SCHRO_PARSE_CODE_INTRA_NON_REF_NOARITH:
      parse_code = "intra non-ref noarith";
      break;
    case SCHRO_PARSE_CODE_INTER_REF_1_NOARITH:
      parse_code = "inter ref 1 noarith";
      break;
    case SCHRO_PARSE_CODE_INTER_REF_2_NOARITH:
      parse_code = "inter ref 2 noarith";
      break;
    case SCHRO_PARSE_CODE_INTER_NON_REF_1_NOARITH:
      parse_code = "inter non-ref 1 noarith";
      break;
    case SCHRO_PARSE_CODE_INTER_NON_REF_2_NOARITH:
      parse_code = "inter non-ref 2 noarith";
      break;
    default:
      parse_code = "unknown";
      break;
  }
  schro_unpack_init_with_data (&unpack, data + 5, size - 5, 1);

  next = schro_unpack_decode_bits (&unpack, 32);
  prev = schro_unpack_decode_bits (&unpack, 32);

  if (data[4] == SCHRO_PARSE_CODE_SEQUENCE_HEADER) {
    printf("AU\n");
    printf("pictur: ");
    printf("    ");
    printf("  ");
    printf("  ref1 ");
    printf("  ref2 ");
    printf("retire ");
    printf("     size \n");
  } else if (SCHRO_PARSE_CODE_IS_PICTURE(data[4])) {
    int num_refs = SCHRO_PARSE_CODE_NUM_REFS(data[4]);
    int pic_num;
    char ref_chars[3] = { 'I', 'P', 'B' };

    schro_unpack_byte_sync(&unpack);
    pic_num = schro_unpack_decode_bits(&unpack, 32);
    printf("%6d: ", pic_num);
    if (SCHRO_PARSE_CODE_IS_REFERENCE(data[4])) {
      printf("ref ");
    } else {
      printf("    ");
    }

    printf("%c ", ref_chars[num_refs]);

    if (num_refs > 0) {
      printf("%6d ", pic_num + schro_unpack_decode_sint(&unpack));
    } else {
      printf("       ");
    }
    if (num_refs > 1) {
      printf("%6d ", pic_num + schro_unpack_decode_sint(&unpack));
    } else {
      printf("       ");
    }

    if (SCHRO_PARSE_CODE_IS_REFERENCE(data[4])) {
      int r = schro_unpack_decode_sint(&unpack);
      if (r == 0) {
        printf("  none ");
      } else {
        printf("%6d ", pic_num + r);
      }
    } else {
      printf("       ");
    }
    printf(" %8d\n", next);
  } else if (data[4] == SCHRO_PARSE_CODE_AUXILIARY_DATA) {
  }

  schro_unpack_byte_sync (&unpack);
}