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; |