Example #1
0
static int Fieldcopy(void *dest, const void *src, size_t count,
                     int rows, int dst_pitch, int src_pitch)
{
   unsigned char* pDest = (unsigned char*) dest;
   unsigned char* pSrc = (unsigned char*) src;
   int i;

   for (i=0; i < rows; i++) {
       xine_fast_memcpy(pDest, pSrc, count);
       pSrc += src_pitch;
       pDest += dst_pitch;
   }
   return 0;
}
Example #2
0
static void mad_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) {

  mad_decoder_t *this = (mad_decoder_t *) this_gen;
  int bytes_in_buffer_at_pts;

  lprintf ("decode data, size: %d, decoder_flags: %d\n", buf->size, buf->decoder_flags);

  if (buf->size>(INPUT_BUF_SIZE-this->bytes_in_buffer)) {
    xprintf (this->xstream->xine, XINE_VERBOSITY_DEBUG,
	     "libmad: ALERT input buffer too small (%d bytes, %d avail)!\n",
	     buf->size, INPUT_BUF_SIZE-this->bytes_in_buffer);
    buf->size = INPUT_BUF_SIZE-this->bytes_in_buffer;
  }

  if ((buf->decoder_flags & BUF_FLAG_HEADER) == 0) {

    /* reset decoder on leaving preview mode */
    if ((buf->decoder_flags & BUF_FLAG_PREVIEW) == 0) {
      if (this->preview_mode) {
	mad_reset (this_gen);
      }
    } else {
      this->preview_mode = 1;
    }

    bytes_in_buffer_at_pts = this->bytes_in_buffer;

    xine_fast_memcpy (&this->buffer[this->bytes_in_buffer],
                        buf->content, buf->size);
    this->bytes_in_buffer += buf->size;

    /*
    printf ("libmad: decode data - doing it\n");
    */

    mad_stream_buffer (&this->stream, this->buffer,
		       this->bytes_in_buffer);

    if (this->bytes_in_buffer < MAD_MIN_SIZE && buf->pts == 0)
      return;

    if (!this->needs_more_data) {
      this->pts = buf->pts;
      if (buf->decoder_flags & BUF_FLAG_AUDIO_PADDING) {
        this->start_padding = buf->decoder_info[1];
        this->end_padding = buf->decoder_info[2];
      } else {
        this->start_padding = 0;
        this->end_padding = 0;
      }
    }

    while (1) {

      if (mad_frame_decode (&this->frame, &this->stream) != 0) {

	if (this->stream.next_frame) {
	  int num_bytes =
	    this->buffer + this->bytes_in_buffer - this->stream.next_frame;

	  /* printf("libmad: MAD_ERROR_BUFLEN\n"); */

	  memmove(this->buffer, this->stream.next_frame, num_bytes);
	  this->bytes_in_buffer = num_bytes;
	}

	switch (this->stream.error) {

	case MAD_ERROR_BUFLEN:
	  /* libmad wants more data */
	  this->needs_more_data = 1;
	  return;

	default:
	  lprintf ("error 0x%04X, mad_stream_buffer %d bytes\n", this->stream.error, this->bytes_in_buffer);
	  mad_stream_buffer (&this->stream, this->buffer,
			     this->bytes_in_buffer);
	}

      } else {
	int mode = (this->frame.header.mode == MAD_MODE_SINGLE_CHANNEL) ? AO_CAP_MODE_MONO : AO_CAP_MODE_STEREO;

	if (!this->output_open
	    || (this->output_sampling_rate != this->frame.header.samplerate)
	    || (this->output_mode != mode)) {

	  lprintf ("audio sample rate %d mode %08x\n", this->frame.header.samplerate, mode);

          /* the mpeg audio demuxer can set audio bitrate */
          if (! _x_stream_info_get(this->xstream, XINE_STREAM_INFO_AUDIO_BITRATE)) {
            _x_stream_info_set(this->xstream, XINE_STREAM_INFO_AUDIO_BITRATE,
                               this->frame.header.bitrate);
          }

          /* the mpeg audio demuxer can set this meta info */
          if (! _x_meta_info_get(this->xstream, XINE_META_INFO_AUDIOCODEC)) {
            switch (this->frame.header.layer) {
            case MAD_LAYER_I:
              _x_meta_info_set_utf8(this->xstream, XINE_META_INFO_AUDIOCODEC,
                "MPEG audio layer 1 (lib: MAD)");
              break;
            case MAD_LAYER_II:
              _x_meta_info_set_utf8(this->xstream, XINE_META_INFO_AUDIOCODEC,
                "MPEG audio layer 2 (lib: MAD)");
              break;
            case MAD_LAYER_III:
              _x_meta_info_set_utf8(this->xstream, XINE_META_INFO_AUDIOCODEC,
                "MPEG audio layer 3 (lib: MAD)");
              break;
            default:
              _x_meta_info_set_utf8(this->xstream, XINE_META_INFO_AUDIOCODEC,
                "MPEG audio (lib: MAD)");
            }
          }

	  if (this->output_open) {
	    this->xstream->audio_out->close (this->xstream->audio_out, this->xstream);
	    this->output_open = 0;
          }
          if (!this->output_open) {
	    this->output_open = (this->xstream->audio_out->open) (this->xstream->audio_out,
				   this->xstream, 16,
				   this->frame.header.samplerate,
			           mode) ;
          }
          if (!this->output_open) {
            return;
          }
	  this->output_sampling_rate = this->frame.header.samplerate;
	  this->output_mode = mode;
	}

	mad_synth_frame (&this->synth, &this->frame);

	if ( (buf->decoder_flags & BUF_FLAG_PREVIEW) == 0 ) {

	  unsigned int         nchannels, nsamples;
	  mad_fixed_t const   *left_ch, *right_ch;
	  struct mad_pcm      *pcm = &this->synth.pcm;
	  audio_buffer_t      *audio_buffer;
	  uint16_t            *output;
          int                  bitrate;
          int                  pts_offset;

	  audio_buffer = this->xstream->audio_out->get_buffer (this->xstream->audio_out);
	  output = audio_buffer->mem;

	  nchannels = pcm->channels;
	  nsamples  = pcm->length;
	  left_ch   = pcm->samples[0];
	  right_ch  = pcm->samples[1];

	  /* padding */
	  if (this->start_padding || this->end_padding) {
	    /* check padding validity */
	    if (nsamples < (this->start_padding + this->end_padding)) {
	      lprintf("invalid padding data");
	      this->start_padding = 0;
	      this->end_padding = 0;
	    }
	    lprintf("nsamples=%d, start_padding=%d, end_padding=%d\n",
	            nsamples, this->start_padding, this->end_padding);
	    nsamples -= this->start_padding + this->end_padding;
	    left_ch  += this->start_padding;
	    right_ch += this->start_padding;
	  }
	  audio_buffer->num_frames = nsamples;
	  audio_buffer->vpts       = this->pts;

	  while (nsamples--) {
	    /* output sample(s) in 16-bit signed little-endian PCM */

	    *output++ = scale(*left_ch++);

	    if (nchannels == 2)
	      *output++ = scale(*right_ch++);

	  }

	  audio_buffer->num_frames = pcm->length;

          /* pts computing */
          if (this->frame.header.bitrate > 0) {
            bitrate = this->frame.header.bitrate;
          } else {
            bitrate = _x_stream_info_get(this->xstream, XINE_STREAM_INFO_AUDIO_BITRATE);
            lprintf("offset %d bps\n", bitrate);
          }
          audio_buffer->vpts = buf->pts;
          if (audio_buffer->vpts && (bitrate > 0)) {
            pts_offset = (bytes_in_buffer_at_pts * 8 * 90) / (bitrate / 1000);
            lprintf("pts: %"PRId64", offset: %d pts, %d bytes\n", buf->pts, pts_offset, bytes_in_buffer_at_pts);
            if (audio_buffer->vpts < pts_offset)
              pts_offset = audio_buffer->vpts;
            audio_buffer->vpts -= pts_offset;
          }

	  this->xstream->audio_out->put_buffer (this->xstream->audio_out, audio_buffer, this->xstream);

	  this->pts = buf->pts;
	  buf->pts = 0;
	  if (buf->decoder_flags & BUF_FLAG_AUDIO_PADDING) {
	    this->start_padding = buf->decoder_info[1];
	    this->end_padding = buf->decoder_info[2];
	    buf->decoder_info[1] = 0;
	    buf->decoder_info[2] = 0;
	  } else {
	    this->start_padding = 0;
	    this->end_padding = 0;
	  }
	}
	lprintf ("decode worked\n");
      }
    }
  }
}
Example #3
0
static void nsf_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) {

  nsf_decoder_t *this = (nsf_decoder_t *) this_gen;
  audio_buffer_t *audio_buffer;

  if (buf->decoder_flags & BUF_FLAG_HEADER) {

    /* When the engine sends a BUF_FLAG_HEADER flag, it is time to initialize
     * the decoder. The buffer element type has 4 decoder_info fields,
     * 0..3. Field 1 is the sample rate. Field 2 is the bits/sample. Field
     * 3 is the number of channels. */
    this->sample_rate = buf->decoder_info[1];
    this->bits_per_sample = buf->decoder_info[2];
    this->channels = buf->decoder_info[3];

    /* take this opportunity to initialize stream/meta information */
    this->stream->meta_info[XINE_META_INFO_AUDIOCODEC] = strdup("NES Music (Nosefart)");

    this->song_number = buf->content[4];
    /* allocate a buffer for the file */
    this->nsf_size = BE_32(&buf->content[0]);
    this->nsf_file = xine_xmalloc(this->nsf_size);
    this->nsf_index = 0;

    /* peform any other required initialization */
    this->last_pts = -1;
    this->iteration = 0;

    return;
  }

  /* accumulate chunks from the NSF file until whole file is received */
  if (this->nsf_index < this->nsf_size) {
    xine_fast_memcpy(&this->nsf_file[this->nsf_index], buf->content,
      buf->size);
    this->nsf_index += buf->size;

    if (this->nsf_index == this->nsf_size) {
      /* file has been received, proceed to initialize engine */
      nsf_init();
      this->nsf = nsf_load(NULL, this->nsf_file, this->nsf_size);
      if (!this->nsf) {
        printf ("nsf: could not initialize NSF\n");
        /* make the decoder return on every subsequent buffer */
        this->nsf_index = 0;
      }
      this->nsf->current_song = this->song_number;
      nsf_playtrack(this->nsf, this->nsf->current_song, this->sample_rate,
        this->bits_per_sample, this->channels);
    }
    return;
  }

  /* if the audio output is not open yet, open the audio output */
  if (!this->output_open) {
    this->output_open = this->stream->audio_out->open(
      this->stream->audio_out,
      this->stream,
      this->bits_per_sample,
      this->sample_rate,
      (this->channels == 2) ? AO_CAP_MODE_STEREO : AO_CAP_MODE_MONO);
  }

  /* if the audio still isn't open, do not go any further with the decode */
  if (!this->output_open)
    return;

  /* check if a song change was requested */
  if (buf->decoder_info[1]) {
    this->nsf->current_song = buf->decoder_info[1];
    nsf_playtrack(this->nsf, this->nsf->current_song, this->sample_rate,
      this->bits_per_sample, this->channels);
  }

  /* time to decode a frame */
  if (this->last_pts != -1) {

    /* process a frame */
    nsf_frame(this->nsf);

    /* get an audio buffer */
    audio_buffer = this->stream->audio_out->get_buffer (this->stream->audio_out);
    if (audio_buffer->mem_size == 0) {
       printf ("nsf: Help! Allocated audio buffer with nothing in it!\n");
       return;
    }

    apu_process(audio_buffer->mem, this->sample_rate / this->nsf->playback_rate);
    audio_buffer->vpts = buf->pts;
    audio_buffer->num_frames = this->sample_rate / this->nsf->playback_rate;
    this->stream->audio_out->put_buffer (this->stream->audio_out, audio_buffer, this->stream);
  }
  this->last_pts = buf->pts;
}
Example #4
0
static void rgb_decode_data (video_decoder_t *this_gen,
  buf_element_t *buf) {

  rgb_decoder_t *this = (rgb_decoder_t *) this_gen;
  xine_bmiheader *bih;
  palette_entry_t *palette;
  int i;
  int pixel_ptr, row_ptr;
  int palette_index;
  int buf_ptr;
  unsigned int packed_pixel;
  unsigned char r, g, b;
  int pixels_left;
  unsigned char pixel_byte = 0;

  vo_frame_t *img; /* video out frame */

  /* a video decoder does not care about this flag (?) */
  if (buf->decoder_flags & BUF_FLAG_PREVIEW)
    return;

  if ((buf->decoder_flags & BUF_FLAG_SPECIAL) &&
    (buf->decoder_info[1] == BUF_SPECIAL_PALETTE)) {
    palette = (palette_entry_t *)buf->decoder_info_ptr[2];
    for (i = 0; i < buf->decoder_info[2]; i++) {
      this->yuv_palette[i * 4 + 0] =
        COMPUTE_Y(palette[i].r, palette[i].g, palette[i].b);
      this->yuv_palette[i * 4 + 1] =
        COMPUTE_U(palette[i].r, palette[i].g, palette[i].b);
      this->yuv_palette[i * 4 + 2] =
        COMPUTE_V(palette[i].r, palette[i].g, palette[i].b);
    }
  }

  if (buf->decoder_flags & BUF_FLAG_FRAMERATE) {
    this->video_step = buf->decoder_info[0];
    _x_stream_info_set(this->stream, XINE_STREAM_INFO_FRAME_DURATION, this->video_step);
  }

  if (buf->decoder_flags & BUF_FLAG_STDHEADER) { /* need to initialize */
    (this->stream->video_out->open) (this->stream->video_out, this->stream);

    bih = (xine_bmiheader *) buf->content;
    this->width = (bih->biWidth + 3) & ~0x03;
    this->height = (bih->biHeight + 3) & ~0x03;
    if (this->height < 0) {
      this->upside_down = 1;
      this->height = -this->height;
    } else {
      this->upside_down = 0;
    }
    this->ratio = (double)this->width/(double)this->height;

    this->bit_depth = bih->biBitCount;
    if (this->bit_depth > 32)
      this->bit_depth &= 0x1F;
    /* round this number up in case of 15 */
    lprintf("width = %d, height = %d, bit_depth = %d\n", this->width, this->height, this->bit_depth);

    this->bytes_per_pixel = (this->bit_depth + 1) / 8;

    free (this->buf);

    /* minimal buffer size */
    this->bufsize = this->width * this->height * this->bytes_per_pixel;
    this->buf = calloc(1, this->bufsize);
    this->size = 0;

    init_yuv_planes(&this->yuv_planes, this->width, this->height);

    (this->stream->video_out->open) (this->stream->video_out, this->stream);
    this->decoder_ok = 1;

    /* load the stream/meta info */
    _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "Raw RGB");

    return;
  } else if (this->decoder_ok) {

    if (this->size + buf->size > this->bufsize) {
      this->bufsize = this->size + 2 * buf->size;
      this->buf = realloc (this->buf, this->bufsize);
    }
    xine_fast_memcpy (&this->buf[this->size], buf->content, buf->size);

    this->size += buf->size;

    if (buf->decoder_flags & BUF_FLAG_FRAME_END) {

      img = this->stream->video_out->get_frame (this->stream->video_out,
                                        this->width, this->height,
                                        this->ratio, XINE_IMGFMT_YUY2,
                                        VO_BOTH_FIELDS);

      img->duration  = this->video_step;
      img->pts       = buf->pts;
      img->bad_frame = 0;


      /* iterate through each row */
      buf_ptr = 0;

      if (this->upside_down) {
        for (row_ptr = this->yuv_planes.row_width * (this->yuv_planes.row_count - 1);
          row_ptr >= 0; row_ptr -= this->yuv_planes.row_width) {
          for (pixel_ptr = 0; pixel_ptr < this->width; pixel_ptr++) {

            if (this->bytes_per_pixel == 1) {

              palette_index = this->buf[buf_ptr++];

              this->yuv_planes.y[row_ptr + pixel_ptr] =
                this->yuv_palette[palette_index * 4 + 0];
              this->yuv_planes.u[row_ptr + pixel_ptr] =
                this->yuv_palette[palette_index * 4 + 1];
              this->yuv_planes.v[row_ptr + pixel_ptr] =
                this->yuv_palette[palette_index * 4 + 2];

            } else if (this->bytes_per_pixel == 2) {

              /* ABGR1555 format, little-endian order */
              packed_pixel = _X_LE_16(&this->buf[buf_ptr]);
              buf_ptr += 2;
              UNPACK_BGR15(packed_pixel, r, g, b);

              this->yuv_planes.y[row_ptr + pixel_ptr] =
                COMPUTE_Y(r, g, b);
              this->yuv_planes.u[row_ptr + pixel_ptr] =
                COMPUTE_U(r, g, b);
              this->yuv_planes.v[row_ptr + pixel_ptr] =
                COMPUTE_V(r, g, b);

            } else {

              /* BGR24 or BGRA32 */
              b = this->buf[buf_ptr++];
              g = this->buf[buf_ptr++];
              r = this->buf[buf_ptr++];

              /* the next line takes care of 'A' in the 32-bit case */
              buf_ptr += this->bytes_per_pixel - 3;

              this->yuv_planes.y[row_ptr + pixel_ptr] =
                COMPUTE_Y(r, g, b);
              this->yuv_planes.u[row_ptr + pixel_ptr] =
                COMPUTE_U(r, g, b);
              this->yuv_planes.v[row_ptr + pixel_ptr] =
                COMPUTE_V(r, g, b);

            }
          }
        }
      } else {

        for (row_ptr = 0; row_ptr < this->yuv_planes.row_width * this->yuv_planes.row_count; row_ptr += this->yuv_planes.row_width) {
          pixels_left = 0;
          for (pixel_ptr = 0; pixel_ptr < this->width; pixel_ptr++) {

            if (this->bit_depth == 1) {

              if (pixels_left == 0) {
                pixels_left = 8;
                pixel_byte = *this->buf++;
              }

              if (pixel_byte & 0x80) {
                this->yuv_planes.y[row_ptr + pixel_ptr] =
                  this->yuv_palette[1 * 4 + 0];
                this->yuv_planes.u[row_ptr + pixel_ptr] =
                  this->yuv_palette[1 * 4 + 1];
                this->yuv_planes.v[row_ptr + pixel_ptr] =
                  this->yuv_palette[1 * 4 + 2];
              } else {
                this->yuv_planes.y[row_ptr + pixel_ptr] =
                  this->yuv_palette[0 * 4 + 0];
                this->yuv_planes.u[row_ptr + pixel_ptr] =
                  this->yuv_palette[0 * 4 + 1];
                this->yuv_planes.v[row_ptr + pixel_ptr] =
                  this->yuv_palette[0 * 4 + 2];
              }
              pixels_left--;
              pixel_byte <<= 1;

            } else if (this->bit_depth == 2) {

              if (pixels_left == 0) {
                pixels_left = 4;
                pixel_byte = *this->buf++;
              }

              palette_index = (pixel_byte & 0xC0) >> 6;
              this->yuv_planes.y[row_ptr + pixel_ptr] =
                this->yuv_palette[palette_index * 4 + 0];
              this->yuv_planes.u[row_ptr + pixel_ptr] =
                this->yuv_palette[palette_index * 4 + 1];
              this->yuv_planes.v[row_ptr + pixel_ptr] =
                this->yuv_palette[palette_index * 4 + 2];

              pixels_left--;
              pixel_byte <<= 2;

            } else if (this->bit_depth == 4) {

              if (pixels_left == 0) {
                pixels_left = 2;
                pixel_byte = *this->buf++;
              }

              palette_index = (pixel_byte & 0xF0) >> 4;
              this->yuv_planes.y[row_ptr + pixel_ptr] =
                this->yuv_palette[palette_index * 4 + 0];
              this->yuv_planes.u[row_ptr + pixel_ptr] =
                this->yuv_palette[palette_index * 4 + 1];
              this->yuv_planes.v[row_ptr + pixel_ptr] =
                this->yuv_palette[palette_index * 4 + 2];

              pixels_left--;
              pixel_byte <<= 4;

            } else if (this->bytes_per_pixel == 1) {

              palette_index = this->buf[buf_ptr++];

              this->yuv_planes.y[row_ptr + pixel_ptr] =
                this->yuv_palette[palette_index * 4 + 0];
              this->yuv_planes.u[row_ptr + pixel_ptr] =
                this->yuv_palette[palette_index * 4 + 1];
              this->yuv_planes.v[row_ptr + pixel_ptr] =
                this->yuv_palette[palette_index * 4 + 2];

            } else if (this->bytes_per_pixel == 2) {

              /* ARGB1555 format, big-endian order */
              packed_pixel = _X_BE_16(&this->buf[buf_ptr]);
              buf_ptr += 2;
              UNPACK_RGB15(packed_pixel, r, g, b);

              this->yuv_planes.y[row_ptr + pixel_ptr] =
                COMPUTE_Y(r, g, b);
              this->yuv_planes.u[row_ptr + pixel_ptr] =
                COMPUTE_U(r, g, b);
              this->yuv_planes.v[row_ptr + pixel_ptr] =
                COMPUTE_V(r, g, b);

            } else {

              /* RGB24 or ARGB32; the next line takes care of 'A' in the
               * 32-bit case */
              buf_ptr += this->bytes_per_pixel - 3;

              r = this->buf[buf_ptr++];
              g = this->buf[buf_ptr++];
              b = this->buf[buf_ptr++];

              this->yuv_planes.y[row_ptr + pixel_ptr] =
                COMPUTE_Y(r, g, b);
              this->yuv_planes.u[row_ptr + pixel_ptr] =
                COMPUTE_U(r, g, b);
              this->yuv_planes.v[row_ptr + pixel_ptr] =
                COMPUTE_V(r, g, b);

            }
          }
        }
      }
Example #5
0
static void mad_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) {

  mad_decoder_t *this = (mad_decoder_t *) this_gen;

#ifdef LOG
  printf ("libmad: decode data, decoder_flags: %d\n", buf->decoder_flags);
#endif  
  
  if (buf->size>(INPUT_BUF_SIZE-this->bytes_in_buffer)) {
    printf ("libmad: ALERT input buffer too small (%d bytes, %d avail)!\n",
	    buf->size, INPUT_BUF_SIZE-this->bytes_in_buffer);
    buf->size = INPUT_BUF_SIZE-this->bytes_in_buffer;
  }
  
  if ((buf->decoder_flags & BUF_FLAG_HEADER) == 0) {

    /* reset decoder on leaving preview mode */
    if ((buf->decoder_flags & BUF_FLAG_PREVIEW) == 0) {
      if (this->preview_mode) {
	mad_reset (this_gen);
      }
    } else {
      this->preview_mode = 1;
    }

    xine_fast_memcpy (&this->buffer[this->bytes_in_buffer], 
                        buf->content, buf->size);
    this->bytes_in_buffer += buf->size;
    
    /*
    printf ("libmad: decode data - doing it\n");
    */

    mad_stream_buffer (&this->stream, this->buffer, 
		       this->bytes_in_buffer);

    while (1) {

      if (mad_frame_decode (&this->frame, &this->stream) != 0) {

	if (this->stream.next_frame) {
	  int num_bytes =
	    this->buffer + this->bytes_in_buffer - this->stream.next_frame;
	  
	  /* printf("libmad: MAD_ERROR_BUFLEN\n"); */

	  memmove(this->buffer, this->stream.next_frame, num_bytes);
	  this->bytes_in_buffer = num_bytes;
	}

	switch (this->stream.error) {

	case MAD_ERROR_BUFLEN:
	  return;

	default: 
	  mad_stream_buffer (&this->stream, this->buffer, 
			     this->bytes_in_buffer);
	}

      } else {
	int mode = (this->frame.header.mode == MAD_MODE_SINGLE_CHANNEL) ? AO_CAP_MODE_MONO : AO_CAP_MODE_STEREO;

	if (!this->output_open 
	    || (this->output_sampling_rate != this->frame.header.samplerate)
	    || (this->output_mode != mode)) {

#ifdef LOG
	  printf ("libmad: audio sample rate %d mode %08x\n",
		  this->frame.header.samplerate,
		  mode);
#endif

	  this->xstream->stream_info[XINE_STREAM_INFO_AUDIO_BITRATE] = this->frame.header.bitrate;
	  switch (this->frame.header.layer) {
	  case MAD_LAYER_I:
	    this->xstream->meta_info[XINE_META_INFO_AUDIOCODEC] 
	      = strdup ("MPEG audio layer 1");
	    break;
	  case MAD_LAYER_II:
	    this->xstream->meta_info[XINE_META_INFO_AUDIOCODEC] 
	      = strdup ("MPEG audio layer 2");
	    break;
	  case MAD_LAYER_III:
	    this->xstream->meta_info[XINE_META_INFO_AUDIOCODEC] 
	      = strdup ("MPEG audio layer 3");
	    break;
	  default:
	    this->xstream->meta_info[XINE_META_INFO_AUDIOCODEC] 
	      = strdup ("MPEG audio");
	  }
	  
	  if (this->output_open) {
	    this->xstream->audio_out->close (this->xstream->audio_out, this->xstream);
	    this->output_open = 0;
          }
          if (!this->output_open) {
	    this->output_open = this->xstream->audio_out->open(this->xstream->audio_out,
				   this->xstream, 16,
				   this->frame.header.samplerate, 
			           mode) ;
          }
          if (!this->output_open) {
            return;
          }
	  this->output_sampling_rate = this->frame.header.samplerate;
	  this->output_mode = mode;
	}

	mad_synth_frame (&this->synth, &this->frame);

	if ( (buf->decoder_flags & BUF_FLAG_PREVIEW) == 0 ) {
        
	  unsigned int         nchannels, nsamples;
	  mad_fixed_t const   *left_ch, *right_ch;
	  struct mad_pcm      *pcm = &this->synth.pcm;
	  audio_buffer_t      *audio_buffer;
	  uint16_t            *output;

	  audio_buffer = this->xstream->audio_out->get_buffer (this->xstream->audio_out);
	  output = audio_buffer->mem;

	  nchannels = pcm->channels;
	  nsamples  = pcm->length;
	  left_ch   = pcm->samples[0];
	  right_ch  = pcm->samples[1];
	  
	  while (nsamples--) {
	    /* output sample(s) in 16-bit signed little-endian PCM */
	    
	    *output++ = scale(*left_ch++);
	    
	    if (nchannels == 2) 
	      *output++ = scale(*right_ch++);

	  }

	  audio_buffer->num_frames = pcm->length;
	  audio_buffer->vpts       = buf->pts;

	  this->xstream->audio_out->put_buffer (this->xstream->audio_out, audio_buffer, this->xstream);

	  buf->pts = 0;

	}
#ifdef LOG
	printf ("libmad: decode worked\n"); 
#endif
      }
    } 

  }
}
Example #6
0
static void gsm610_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) {

  gsm610_decoder_t *this = (gsm610_decoder_t *) this_gen;
  audio_buffer_t *audio_buffer;
  int in_ptr;

  if (buf->decoder_flags & BUF_FLAG_STDHEADER) {
    this->sample_rate = buf->decoder_info[1];

    this->buf = calloc(1, AUDIOBUFSIZE);
    this->bufsize = AUDIOBUFSIZE;
    this->size = 0;

    /* stream/meta info */
    _x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC, "GSM 6.10");

    return;
  }

  if (!this->output_open) {

    this->gsm_state = gsm_create();
    this->buf_type = buf->type;

    this->output_open = (this->stream->audio_out->open) (this->stream->audio_out,
      this->stream, GSM610_SAMPLE_SIZE, this->sample_rate, AO_CAP_MODE_MONO);
  }

  /* if the audio still isn't open, bail */
  if (!this->output_open)
    return;

  if( this->size + buf->size > this->bufsize ) {
    this->bufsize = this->size + 2 * buf->size;
    xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
	    "gsm610: increasing source buffer to %d to avoid overflow.\n", this->bufsize);
    this->buf = realloc( this->buf, this->bufsize );
  }

  xine_fast_memcpy (&this->buf[this->size], buf->content, buf->size);
  this->size += buf->size;

  if (buf->decoder_flags & BUF_FLAG_FRAME_END)  { /* time to decode a frame */
    int16_t decode_buffer[GSM610_BLOCK_SIZE];

    /* handle the Microsoft variant of GSM data */
    if (this->buf_type == BUF_AUDIO_MSGSM) {

      this->gsm_state->wav_fmt = 1;

      /* the data should line up on a 65-byte boundary */
      if ((buf->size % 65) != 0) {
        xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG,
		 "gsm610: received MS GSM block that does not line up\n");
        this->size = 0;
        return;
      }

      in_ptr = 0;
      while (this->size) {
        gsm_decode(this->gsm_state, &this->buf[in_ptr], decode_buffer);
        if ((in_ptr % 65) == 0) {
          in_ptr += 33;
          this->size -= 33;
        } else {
          in_ptr += 32;
          this->size -= 32;
        }

        /* dispatch the decoded audio; assume that the audio buffer will
         * always contain at least 160 samples */
        audio_buffer = this->stream->audio_out->get_buffer (this->stream->audio_out);

        xine_fast_memcpy(audio_buffer->mem, decode_buffer,
          GSM610_BLOCK_SIZE * 2);
        audio_buffer->num_frames = GSM610_BLOCK_SIZE;

        audio_buffer->vpts = buf->pts;
        buf->pts = 0;  /* only first buffer gets the real pts */
        this->stream->audio_out->put_buffer (this->stream->audio_out, audio_buffer, this->stream);
      }
    } else {

      /* handle the other variant, which consists of 33-byte blocks */
      this->gsm_state->wav_fmt = 0;

      /* the data should line up on a 33-byte boundary */
      if ((buf->size % 33) != 0) {
        xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "gsm610: received GSM block that does not line up\n");
        this->size = 0;
        return;
      }

      in_ptr = 0;
      while (this->size) {
        gsm_decode(this->gsm_state, &this->buf[in_ptr], decode_buffer);
        in_ptr += 33;
        this->size -= 33;

        /* dispatch the decoded audio; assume that the audio buffer will
         * always contain at least 160 samples */
        audio_buffer = this->stream->audio_out->get_buffer (this->stream->audio_out);

        xine_fast_memcpy(audio_buffer->mem, decode_buffer,
          GSM610_BLOCK_SIZE * 2);
        audio_buffer->num_frames = GSM610_BLOCK_SIZE;

        audio_buffer->vpts = buf->pts;
        buf->pts = 0;  /* only first buffer gets the real pts */
        this->stream->audio_out->put_buffer (this->stream->audio_out, audio_buffer, this->stream);
      }
    }
  }
}
Example #7
0
static void win32_display_frame( vo_driver_t * vo_driver, vo_frame_t * vo_frame )
{
  win32_driver_t  *win32_driver = ( win32_driver_t * ) vo_driver;
  win32_frame_t   *win32_frame  = ( win32_frame_t * ) vo_frame;


  /* if the required width, height or format has changed
   * then recreate the secondary buffer */

  if( ( win32_driver->req_format	!= win32_frame->format	) ||
      ( win32_driver->width		!= win32_frame->width	) ||
      ( win32_driver->height		!= win32_frame->height	) )
    {
      CreateSecondary( win32_driver, win32_frame->width, win32_frame->height, win32_frame->format );
    }

  /* determine desired ratio */

  win32_driver->ratio = win32_frame->ratio;

  /* lock our surface to update its contents */

  win32_driver->contents = Lock( win32_driver, win32_driver->secondary );

  /* surface unavailable, skip frame render */

  if( !win32_driver->contents )
    {
      vo_frame->free( vo_frame );
      return;
    }

  /* if our actual frame format is the native screen
   * pixel format, we need to convert it */

  if( win32_driver->act_format == IMGFMT_NATIVE )
    {
      /* use the software color conversion functions
       * to rebuild the frame in our native screen
       * pixel format ... this is slow */

      if( win32_driver->req_format == XINE_IMGFMT_YV12 )
	{
	  /* convert from yv12 to native
	   * screen pixel format */

#if NEW_YUV
	  win32_driver->yuv2rgb->configure( win32_driver->yuv2rgb,
					    win32_driver->width, win32_driver->height,
					    win32_frame->vo_frame.pitches[0], win32_frame->vo_frame.pitches[1],
					    win32_driver->width, win32_driver->height,
					    win32_driver->width * win32_driver->bytespp);
#else
	  yuv2rgb_setup( win32_driver->yuv2rgb,
			 win32_driver->width, win32_driver->height,
			 win32_frame->vo_frame.pitches[0], win32_frame->vo_frame.pitches[1],
			 win32_driver->width, win32_driver->height,
			 win32_driver->width * win32_driver->bytespp );

#endif

	  win32_driver->yuv2rgb->yuv2rgb_fun( win32_driver->yuv2rgb,
					      win32_driver->contents,
					      win32_frame->vo_frame.base[0],
					      win32_frame->vo_frame.base[1],
					      win32_frame->vo_frame.base[2] );
	}

      if( win32_driver->req_format == XINE_IMGFMT_YUY2 )
	{
	  /* convert from yuy2 to native
	   * screen pixel format */
#if NEW_YUV
	  win32_driver->yuv2rgb->configure( win32_driver->yuv2rgb,
					    win32_driver->width, win32_driver->height,
					    win32_frame->vo_frame.pitches[0], win32_frame->vo_frame.pitches[0] / 2,
					    win32_driver->width, win32_driver->height,
					    win32_driver->width * win32_driver->bytespp );
#else

	  yuv2rgb_setup( win32_driver->yuv2rgb,
			 win32_driver->width, win32_driver->height,
			 win32_frame->vo_frame.pitches[0], win32_frame->vo_frame.pitches[0] / 2,
			 win32_driver->width, win32_driver->height,
			 win32_driver->width * win32_driver->bytespp );

#endif
	  win32_driver->yuv2rgb->yuy22rgb_fun( win32_driver->yuv2rgb,
					       win32_driver->contents,
					       win32_frame->vo_frame.base[0] );
	}

#if RGB_SUPPORT
      if( win32_driver->req_format == IMGFMT_RGB )
	{
	  /* convert from 24 bit rgb to native
	   * screen pixel format */

	  /* TODO : rgb2rgb conversion */
	}
#endif
    }
  else
    {
      /* the actual format is identical to our
       * stream format. we just need to copy it */

    int line;
    uint8_t * src;
    vo_frame_t * frame = vo_frame;
    uint8_t * dst = (uint8_t *)win32_driver->contents;

    switch(win32_frame->format)
	{
      case XINE_IMGFMT_YV12:
        src = frame->base[0];
        for (line = 0; line < frame->height ; line++){
          xine_fast_memcpy( dst, src, frame->width);
          src += vo_frame->pitches[0];
          dst += win32_driver->ddsd.lPitch;
        }

        src = frame->base[2];
        for (line = 0; line < frame->height/2 ; line++){
          xine_fast_memcpy( dst, src, frame->width/2);
          src += vo_frame->pitches[2];
          dst += win32_driver->ddsd.lPitch/2;
        }

        src = frame->base[1];
        for (line = 0; line < frame->height/2 ; line++){
          xine_fast_memcpy( dst, src, frame->width/2);
          src += vo_frame->pitches[1];
          dst += win32_driver->ddsd.lPitch/2;
        }
	  break;

	case XINE_IMGFMT_YUY2:
	default:
      src = frame->base[0];
      for (line = 0; line < frame->height ; line++){
	    xine_fast_memcpy( dst, src, frame->width*2);
	    src += vo_frame->pitches[0];
	    dst += win32_driver->ddsd.lPitch;
	  }
	  break;
	}
  }

  /* unlock the surface  */

  Unlock( win32_driver->secondary );

  /* scale, clip and display our frame */

  DisplayFrame( win32_driver );

  /* tag our frame as displayed */
  if((win32_driver->current != NULL) && ((vo_frame_t *)win32_driver->current != vo_frame)) {
    vo_frame->free(&win32_driver->current->vo_frame);
  }
  win32_driver->current = (win32_frame_t *)vo_frame;

}
Example #8
0
void *xine_memdup0 (const void *src, size_t length)
{
  char *dst = xine_xmalloc (length + 1);
  dst[length] = 0;
  return xine_fast_memcpy (dst, src, length);
}
Example #9
0
void *xine_memdup (const void *src, size_t length)
{
  void *dst = malloc (length);
  return xine_fast_memcpy (dst, src, length);
}
Example #10
0
static void fooaudio_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) {

  fooaudio_decoder_t *this = (fooaudio_decoder_t *) this_gen;
  audio_buffer_t *audio_buffer;
  int i;
  int64_t samples_to_generate;
  int samples_to_send;

  if (buf->decoder_flags & BUF_FLAG_STDHEADER) {

    /* When the engine sends a BUF_FLAG_HEADER flag, it is time to initialize
     * the decoder. The buffer element type has 4 decoder_info fields,
     * 0..3. Field 1 is the sample rate. Field 2 is the bits/sample. Field
     * 3 is the number of channels. */
    this->sample_rate = buf->decoder_info[1];
    this->bits_per_sample = buf->decoder_info[2];
    this->channels = buf->decoder_info[3];

    /* initialize the data accumulation buffer */
    this->buf = calloc(1, AUDIOBUFSIZE);
    this->bufsize = AUDIOBUFSIZE;
    this->size = 0;

    /* take this opportunity to initialize stream/meta information */
    _x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC, "fooaudio");

    /* perform any other required initialization */
    this->last_pts = -1;
    this->iteration = 0;

    return;
  }

  /* if the audio output is not open yet, open the audio output */
#warning: Audio output is hardcoded to mono 16-bit PCM
  if (!this->output_open) {
    this->output_open = (this->stream->audio_out->open) (
      this->stream->audio_out,
      this->stream,
/*      this->bits_per_sample, */
      16,
      this->sample_rate,
/*      _x_ao_channels2mode(this->channels));*/
      AO_CAP_MODE_MONO);
  }

  /* if the audio still isn't open, do not go any further with the decode */
  if (!this->output_open)
    return;

  /* accumulate the data passed through the buffer element type; increase
   * the accumulator buffer size as necessary */
  if( this->size + buf->size > this->bufsize ) {
    this->bufsize = this->size + 2 * buf->size;
    xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
	    "fooaudio: increasing source buffer to %d to avoid overflow.\n", this->bufsize);
    this->buf = realloc( this->buf, this->bufsize );
  }
  xine_fast_memcpy (&this->buf[this->size], buf->content, buf->size);
  this->size += buf->size;

  /* When a buffer element type has the BUF_FLAG_FRAME_END flag set, it is
   * time to decode the data in the buffer. */
  if (buf->decoder_flags & BUF_FLAG_FRAME_END)  {

    /* This is where the real meat of the audio decoder is implemented.
     * The general strategy is to decode the data in the accumulation buffer
     * into raw PCM data and then dispatch the PCM to the engine in smaller
     * buffers. What follows in the inside of this scope is the meat of
     * this particular audio decoder. */

    /* Operation of the fooaudio decoder:
     * This decoder generates a continuous sine pattern based on the pts
     * values sent by the xine engine. Two pts values are needed to know
     * how long to make the audio. Thus, If this is the first frame or
     * a seek has occurred (indicated by this->last_pts = -1),
     * log the pts but do not create any audio.
     *
     * When a valid pts delta is generated, create n audio samples, where
     * n is given as:
     *
     *       n          pts delta
     *  -----------  =  ---------  =>  n = (pts delta * sample rate) / 90000
     *  sample rate       90000
     *
     */

    if (this->last_pts != -1) {

      /* no real reason to set this variable to 0 first; I just wanted the
       * novelty of using all 4 basic arithmetic ops in a row (+ - * /) */
      samples_to_generate = 0;
      samples_to_generate += buf->pts;
      samples_to_generate -= this->last_pts;
      samples_to_generate *= this->sample_rate;
      samples_to_generate /= 90000;

      /* save the pts now since it will likely be trashed later */
      this->last_pts = buf->pts;

      while (samples_to_generate) {

        /* get an audio buffer */
        audio_buffer = this->stream->audio_out->get_buffer (this->stream->audio_out);
        if (audio_buffer->mem_size == 0) {
          xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG,
		   "fooaudio: Help! Allocated audio buffer with nothing in it!\n");
          return;
        }

        /* samples_to_generate is a sample count; mem_size is a byte count */
        if (samples_to_generate > audio_buffer->mem_size / 2)
          samples_to_send = audio_buffer->mem_size / 2;
        else
          samples_to_send = samples_to_generate;
        samples_to_generate -= samples_to_send;

#define WAVE_HZ 300
        /* fill up the samples in the buffer */
        for (i = 0; i < samples_to_send; i++)
          audio_buffer->mem[i] =
            (short)(sin(2 * M_PI * this->iteration++ / WAVE_HZ) * 32767);

        /* final prep for audio buffer dispatch */
        audio_buffer->num_frames = samples_to_send;
        audio_buffer->vpts = buf->pts;
        buf->pts = 0;  /* only first buffer gets the real pts */
        this->stream->audio_out->put_buffer (this->stream->audio_out, audio_buffer, this->stream);

      }
    } else {
      /* log the pts for the next time */
      this->last_pts = buf->pts;
    }

    /* reset data accumulation buffer */
    this->size = 0;
  }
}