diff options
Diffstat (limited to 'src/demuxers/demux_yuv4mpeg2.c')
| -rw-r--r-- | src/demuxers/demux_yuv4mpeg2.c | 114 | 
1 files changed, 47 insertions, 67 deletions
| diff --git a/src/demuxers/demux_yuv4mpeg2.c b/src/demuxers/demux_yuv4mpeg2.c index 9c5856710..aa1a4dff6 100644 --- a/src/demuxers/demux_yuv4mpeg2.c +++ b/src/demuxers/demux_yuv4mpeg2.c @@ -69,7 +69,7 @@ typedef struct {    int                  aspect_d;    int                  progressive;    int                  top_field_first; -   +    unsigned int         frame_pts_inc;    unsigned int         frame_size; @@ -86,7 +86,7 @@ static int open_yuv4mpeg2_file(demux_yuv4mpeg2_t *this) {    char *header_ptr, *header_endptr, *header_end;    this->bih.biWidth = this->bih.biHeight = this->fps_n = this->fps_d = -    this->aspect_n = this->aspect_d = this->progressive =  +    this->aspect_n = this->aspect_d = this->progressive =      this->top_field_first = this->data_start = 0;    if (_x_demux_read_header(this->input, header, Y4M_HEADER_BYTES) != Y4M_HEADER_BYTES) @@ -98,11 +98,11 @@ static int open_yuv4mpeg2_file(demux_yuv4mpeg2_t *this) {    /* null terminate the read data */    header[Y4M_HEADER_BYTES] = '\0'; -   +    /* check for stream header terminator */    if ((header_end = strchr(header, '\n')) == NULL)      return 0; -   +    /* read tagged fields in stream header */    header_ptr = &header[Y4M_SIGNATURE_SIZE];    while (header_ptr < header_end) { @@ -111,7 +111,7 @@ static int open_yuv4mpeg2_file(demux_yuv4mpeg2_t *this) {        break;      else        header_ptr++; -   +      switch (*header_ptr) {        case 'W':          /* read the width */ @@ -153,31 +153,31 @@ static int open_yuv4mpeg2_file(demux_yuv4mpeg2_t *this) {            return 0;          else            header_ptr = header_endptr; -           +          /* denominator */          this->fps_d = strtol(header_ptr + 1, &header_endptr, 10);          if (header_endptr == header_ptr + 1)            return 0;          else            header_ptr = header_endptr; -         +          break;        case 'A': -        /* read aspect ratio - stored as a ratio(!)  +        /* read aspect ratio - stored as a ratio(!)           * numerator */          this->aspect_n = strtol(header_ptr + 1, &header_endptr, 10);          if ((header_endptr == header_ptr + 1) || (*header_endptr != ':'))            return 0;          else            header_ptr = header_endptr; -           +          /* denominator */          this->aspect_d = strtol(header_ptr + 1, &header_endptr, 10);          if (header_endptr == header_ptr + 1)            return 0;          else            header_ptr = header_endptr; -         +          break;        default:          /* skip whatever this is */ @@ -185,7 +185,7 @@ static int open_yuv4mpeg2_file(demux_yuv4mpeg2_t *this) {            header_ptr++;      }    } -   +    /* make sure all the data was found */    if (!this->bih.biWidth || !this->bih.biHeight || !this->fps_n || !this->fps_d)      return 0; @@ -194,25 +194,17 @@ static int open_yuv4mpeg2_file(demux_yuv4mpeg2_t *this) {    this->frame_size = this->bih.biWidth * this->bih.biHeight * 3 / 2;    /* pts difference between frames */ -  this->frame_pts_inc = (90000 * this->fps_d) / this->fps_n;   -   +  this->frame_pts_inc = (90000 * this->fps_d) / this->fps_n; +    /* finally, look for the first frame */ -  while ((header_ptr - header) < (Y4M_HEADER_BYTES - 4)) { -    if((header_ptr[0] == 'F') && -       (header_ptr[1] == 'R') && -       (header_ptr[2] == 'A') && -       (header_ptr[3] == 'M') && -       (header_ptr[4] == 'E')) { -      this->data_start = header_ptr - header; -      break; -    } else  -      header_ptr++; -  } -   +  char *data_start_ptr = memmem(header_ptr, Y4M_HEADER_BYTES, "FRAME", 5); +    /* make sure the first frame was found */ -  if(!this->data_start) +  if ( !data_start_ptr )      return 0; -   + +  this->data_start = data_start_ptr - header; +    /* compute size of all frames */    if (INPUT_IS_SEEKABLE(this->input)) {      this->data_size = this->input->get_length(this->input) - @@ -228,29 +220,26 @@ static int open_yuv4mpeg2_file(demux_yuv4mpeg2_t *this) {  static int demux_yuv4mpeg2_send_chunk(demux_plugin_t *this_gen) {    demux_yuv4mpeg2_t *this = (demux_yuv4mpeg2_t *) this_gen; -  buf_element_t *buf = NULL; -  unsigned char preamble[Y4M_FRAME_SIGNATURE_SIZE]; -  int bytes_remaining; -  off_t current_file_pos; -  int64_t pts; -    /* validate that this is an actual frame boundary */ -  if (this->input->read(this->input, preamble, Y4M_FRAME_SIGNATURE_SIZE) != -    Y4M_FRAME_SIGNATURE_SIZE) { -    this->status = DEMUX_FINISHED; -    return this->status; -  } -  if (memcmp(preamble, Y4M_FRAME_SIGNATURE, Y4M_FRAME_SIGNATURE_SIZE) != -    0) { -    this->status = DEMUX_FINISHED; -    return this->status; +  { +    uint8_t preamble[Y4M_FRAME_SIGNATURE_SIZE]; +    if (this->input->read(this->input, preamble, Y4M_FRAME_SIGNATURE_SIZE) != +	Y4M_FRAME_SIGNATURE_SIZE) { +      this->status = DEMUX_FINISHED; +      return this->status; +    } +    if (memcmp(preamble, Y4M_FRAME_SIGNATURE, Y4M_FRAME_SIGNATURE_SIZE) != +	0) { +      this->status = DEMUX_FINISHED; +      return this->status; +    }    }    /* load and dispatch the raw frame */ -  bytes_remaining = this->frame_size; -  current_file_pos = +  int bytes_remaining = this->frame_size; +  off_t current_file_pos =      this->input->get_current_pos(this->input) - this->data_start; -  pts = current_file_pos; +  int64_t pts = current_file_pos;    pts /= (this->frame_size + Y4M_FRAME_SIGNATURE_SIZE);    pts *= this->frame_pts_inc; @@ -261,17 +250,14 @@ static int demux_yuv4mpeg2_send_chunk(demux_plugin_t *this_gen) {    }    while(bytes_remaining) { -    buf = this->video_fifo->buffer_pool_alloc (this->video_fifo); +    buf_element_t *buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);      buf->type = BUF_VIDEO_I420;      if( this->data_size )        buf->extra_info->input_normpos = (int)((double) current_file_pos * 65535 / this->data_size);      buf->extra_info->input_time = pts / 90;      buf->pts = pts; -    if (bytes_remaining > buf->max_size) -      buf->size = buf->max_size; -    else -      buf->size = bytes_remaining; +    buf->size = MIN(bytes_remaining, buf->max_size);      bytes_remaining -= buf->size;      if (this->input->read(this->input, buf->content, buf->size) != @@ -285,13 +271,12 @@ static int demux_yuv4mpeg2_send_chunk(demux_plugin_t *this_gen) {        buf->decoder_flags |= BUF_FLAG_FRAME_END;      this->video_fifo->put(this->video_fifo, buf);    } -   +    return this->status; -}  +}  static void demux_yuv4mpeg2_send_headers(demux_plugin_t *this_gen) {    demux_yuv4mpeg2_t *this = (demux_yuv4mpeg2_t *) this_gen; -  buf_element_t *buf;    this->video_fifo  = this->stream->video_fifo;    this->audio_fifo  = this->stream->audio_fifo; @@ -310,17 +295,17 @@ static void demux_yuv4mpeg2_send_headers(demux_plugin_t *this_gen) {    _x_demux_control_start(this->stream);    /* send init info to decoders */ -  buf = this->video_fifo->buffer_pool_alloc (this->video_fifo); +  buf_element_t *buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);    buf->decoder_flags = BUF_FLAG_HEADER|BUF_FLAG_STDHEADER|BUF_FLAG_FRAMERATE|                         BUF_FLAG_FRAME_END;    buf->decoder_info[0] = this->frame_pts_inc;  /* initial video step */ -   +    if(this->aspect_n && this->aspect_d) {      buf->decoder_flags  |= BUF_FLAG_ASPECT;      buf->decoder_info[1] = this->bih.biWidth * this->aspect_n;      buf->decoder_info[2] = this->bih.biHeight * this->aspect_d;    } -     +    buf->decoder_info[3] = this->progressive;    buf->decoder_info[4] = this->top_field_first; @@ -342,7 +327,7 @@ static int demux_yuv4mpeg2_seek (demux_plugin_t *this_gen,       /* YUV4MPEG2 files are essentially constant bit-rate video. Seek along        * the calculated frame boundaries. Divide the requested seek offset -      * by the frame size integer-wise to obtain the desired frame number  +      * by the frame size integer-wise to obtain the desired frame number        * and then multiply the frame number by the frame size to get the        * starting offset. Add the data_start offset to obtain the final        * offset. */ @@ -385,7 +370,7 @@ static int demux_yuv4mpeg2_get_status (demux_plugin_t *this_gen) {  static int demux_yuv4mpeg2_get_stream_length (demux_plugin_t *this_gen) {    demux_yuv4mpeg2_t *this = (demux_yuv4mpeg2_t *) this_gen; -  return (int)(((int64_t) this->data_size * 1000 * this->fps_d) /  +  return (int)(((int64_t) this->data_size * 1000 * this->fps_d) /                 ((this->frame_size + Y4M_FRAME_SIGNATURE_SIZE) * this->fps_n));  } @@ -400,10 +385,7 @@ static int demux_yuv4mpeg2_get_optional_data(demux_plugin_t *this_gen,  static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *stream,                                      input_plugin_t *input) { - -  demux_yuv4mpeg2_t *this; - -  this         = xine_xmalloc (sizeof (demux_yuv4mpeg2_t)); +  demux_yuv4mpeg2_t *this = calloc(1, sizeof(demux_yuv4mpeg2_t));    this->stream = stream;    this->input  = input; @@ -422,10 +404,8 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str    switch (stream->content_detection_method) {    case METHOD_BY_EXTENSION: { -    const char *extensions, *mrl; - -    mrl = input->get_mrl (input); -    extensions = class_gen->get_extensions (class_gen); +    const char *const mrl = input->get_mrl (input); +    const char *const extensions = class_gen->get_extensions (class_gen);      if (!_x_demux_check_extension (mrl, extensions)) {        free (this); @@ -477,7 +457,7 @@ static void class_dispose (demux_class_t *this_gen) {  static void *init_plugin (xine_t *xine, void *data) {    demux_yuv4mpeg2_class_t     *this; -  this = xine_xmalloc (sizeof (demux_yuv4mpeg2_class_t)); +  this = calloc(1, sizeof(demux_yuv4mpeg2_class_t));    this->demux_class.open_plugin     = open_plugin;    this->demux_class.get_description = get_description; | 
