📄 pmp_read.c.svn-base
字号:
/*
PMP Mod
Copyright (C) 2006 jonny
Homepage: http://jonny.leffe.dnsalias.com
E-mail: jonny@leffe.dnsalias.com
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
basic layer for reading av frames
*/
#include "pmp_read.h"
void pmp_read_safe_constructor(struct pmp_read_struct *p)
{
pmp_file_safe_constructor(&p->file);
p->f = -1;
p->buffer_0 = 0;
p->buffer_1 = 0;
p->packet_header = 0;
}
void pmp_read_close(struct pmp_read_struct *p)
{
pmp_file_close(&p->file);
if (!(p->f < 0)) sceIoClose(p->f);
if (p->buffer_0 != 0) free_64(p->buffer_0);
if (p->buffer_1 != 0) free_64(p->buffer_1);
if (p->packet_header != 0) free_64(p->packet_header);
pmp_read_safe_constructor(p);
}
static char *fill_asynchronous_buffer(struct pmp_read_struct *reader, struct asynchronous_buffer *p, unsigned int first_packet, unsigned int first_packet_position, unsigned int seek)
{
p->first_packet = first_packet;
p->last_packet = first_packet;
p->packets_size = reader->file.packet_index[first_packet] >> 1;
p->packet_buffer[0] = p->buffer + (first_packet_position & (64 - 1));
unsigned int number_of_packets = 1;
if (seek == 0)
{
while (1)
{
if (p->last_packet + 1 == reader->file.header.video.number_of_frames)
{
break;
}
if (number_of_packets == maximum_number_of_packets)
{
break;
}
unsigned int next_packet_size = reader->file.packet_index[p->last_packet + 1] >> 1;
if (p->packets_size + next_packet_size > reader->buffer_size)
{
break;
}
p->packet_buffer[number_of_packets] = p->packet_buffer[0] + p->packets_size;
p->packets_size += next_packet_size;
p->last_packet ++;
number_of_packets ++;
}
}
p->first_packet_position = first_packet_position;
p->next_packet_position = first_packet_position + p->packets_size;
if (sceIoLseek32(reader->f, p->first_packet_position, PSP_SEEK_SET) != p->first_packet_position)
{
return("fill_asynchronous_buffer: seek failed");
}
if (sceIoReadAsync(reader->f, p->packet_buffer[0], p->packets_size) < 0)
{
return("fill_asynchronous_buffer: read failed");
}
return(0);
}
static char *wait_asynchronous_buffer(struct pmp_read_struct *reader, struct asynchronous_buffer *p)
{
long long result;
if (sceIoWaitAsync(reader->f, &result) < 0)
{
return("wait_asynchronous_buffer: wait failed");
}
if (p->packets_size != result)
{
return("wait_asynchronous_buffer: read failed");
}
return(0);
}
static char *fill_and_wait_asynchronous_buffer(struct pmp_read_struct *reader, struct asynchronous_buffer *p, unsigned int first_packet, unsigned int first_packet_position, unsigned int seek)
{
char *result = fill_asynchronous_buffer(reader, p, first_packet, first_packet_position, seek);
if (result != 0)
{
return(result);
}
result = wait_asynchronous_buffer(reader, p);
if (result != 0)
{
return(result);
}
return(0);
}
static char *fill_next_asynchronous_buffer(struct pmp_read_struct *reader, unsigned int seek)
{
unsigned int first_packet = reader->current_asynchronous_buffer->last_packet + 1;
unsigned int first_packet_position = reader->current_asynchronous_buffer->next_packet_position;
if (first_packet == reader->file.header.video.number_of_frames)
{
first_packet = 0;
first_packet_position = reader->file.packet_start;
}
char *result = fill_asynchronous_buffer(reader, reader->next_asynchronous_buffer, first_packet, first_packet_position, seek);
if (result != 0)
{
return(result);
}
return(0);
}
static char *fill_current_and_next_asynchronous_buffer(struct pmp_read_struct *reader, unsigned int first_packet, unsigned int first_packet_position, unsigned int seek)
{
char *result = fill_and_wait_asynchronous_buffer(reader, reader->current_asynchronous_buffer, first_packet, first_packet_position, seek);
if (result != 0)
{
return(result);
}
result = fill_next_asynchronous_buffer(reader, seek);
if (result != 0)
{
return(result);
}
return(0);
}
static void swap_asynchronous_buffers(struct pmp_read_struct *reader)
{
struct asynchronous_buffer *swap = reader->current_asynchronous_buffer;
reader->current_asynchronous_buffer = reader->next_asynchronous_buffer;
reader->next_asynchronous_buffer = swap;
}
static unsigned int get_packet_position(struct pmp_read_struct *reader, unsigned int packet)
{
unsigned int first_packet = reader->current_asynchronous_buffer->first_packet;
unsigned int first_packet_position = reader->current_asynchronous_buffer->first_packet_position;
if (packet >= first_packet)
{
while (first_packet != packet)
{
first_packet_position += reader->file.packet_index[first_packet] >> 1;
first_packet ++;
}
}
else
{
while (first_packet != packet)
{
first_packet --;
first_packet_position -= reader->file.packet_index[first_packet] >> 1;
}
}
return(first_packet_position);
}
char *pmp_read_open(struct pmp_read_struct *p, unsigned int padding, char *s)
{
pmp_read_safe_constructor(p);
char *result = pmp_file_open(&p->file, s);
if (result != 0)
{
pmp_read_close(p);
return(result);
}
p->f = sceIoOpen(s, PSP_O_RDONLY, 0777);
if (p->f < 0)
{
pmp_read_close(p);
return("pmp_read_open: can't open file");
}
if (sceIoChangeAsyncPriority(p->f, 0x10) < 0)
{
pmp_read_close(p);
return("pmp_read_open: sceIoChangeAsyncPriority failed");
}
p->buffer_size = minimum_buffer_size;
if (p->file.maximum_packet_size > p->buffer_size)
{
p->buffer_size = p->file.maximum_packet_size;
}
p->buffer_0 = malloc_64(p->buffer_size + padding + 64);
if (p->buffer_0 == 0)
{
pmp_read_close(p);
return("pmp_read_open: malloc_64 failed on buffer_0");
}
memset(p->buffer_0, 0, p->buffer_size + padding + 64);
p->buffer_1 = malloc_64(p->buffer_size + padding + 64);
if (p->buffer_1 == 0)
{
pmp_read_close(p);
return("pmp_read_open: malloc_64 failed on buffer_1");
}
memset(p->buffer_1, 0, p->buffer_size + padding + 64);
p->packet_header = malloc_64(sizeof(unsigned int) * (p->file.header.audio.maximum_number_of_frames * p->file.header.audio.number_of_streams + 3));
if (p->packet_header == 0)
{
pmp_read_close(p);
return("pmp_read_open: malloc_64 failed on packet_header");
}
p->asynchronous_buffer_0.buffer = p->buffer_0;
p->asynchronous_buffer_1.buffer = p->buffer_1;
p->current_asynchronous_buffer = &p->asynchronous_buffer_0;
p->next_asynchronous_buffer = &p->asynchronous_buffer_1;
result = fill_current_and_next_asynchronous_buffer(p, 0, p->file.packet_start, 0);
if (result != 0)
{
pmp_read_close(p);
return(result);
}
return(0);
}
static char *get_packet(struct pmp_read_struct *reader, unsigned int packet, void **buffer)
{
if (packet >= reader->current_asynchronous_buffer->first_packet && packet <= reader->current_asynchronous_buffer->last_packet)
{
*buffer = reader->current_asynchronous_buffer->packet_buffer[packet - reader->current_asynchronous_buffer->first_packet];
}
else
{
char *result = wait_asynchronous_buffer(reader, reader->next_asynchronous_buffer);
if (result != 0)
{
return(result);
}
if (packet >= reader->next_asynchronous_buffer->first_packet && packet <= reader->next_asynchronous_buffer->last_packet)
{
swap_asynchronous_buffers(reader);
result = fill_next_asynchronous_buffer(reader, 0);
if (result != 0)
{
return(result);
}
*buffer = reader->current_asynchronous_buffer->packet_buffer[packet - reader->current_asynchronous_buffer->first_packet];
}
else
{
unsigned int packet_position = get_packet_position(reader, packet);
result = fill_current_and_next_asynchronous_buffer(reader, packet, packet_position, 1);
if (result != 0)
{
return(result);
}
*buffer = reader->current_asynchronous_buffer->packet_buffer[0];
}
}
return(0);
}
char *pmp_read_get(struct pmp_read_struct *p, unsigned int packet, unsigned int audio_stream, struct pmp_read_output_struct *output)
{
void *buffer;
char *result = get_packet(p, packet, &buffer);
if (result != 0)
{
return(result);
}
unsigned char number_of_audio_frames = *((unsigned char *) buffer);
output->number_of_audio_frames = number_of_audio_frames;
unsigned int size_of_unsigned_int_fields = sizeof(unsigned int) * (output->number_of_audio_frames * p->file.header.audio.number_of_streams + 3);
memcpy(p->packet_header, buffer + 1, size_of_unsigned_int_fields);
output->first_delay = p->packet_header[0];
output->last_delay = p->packet_header[1];
output->video_length = p->packet_header[2];
output->audio_length = &p->packet_header[3];
output->video_buffer = buffer + size_of_unsigned_int_fields + 1;
output->audio_buffer = output->video_buffer + output->video_length;
unsigned int skip = audio_stream * output->number_of_audio_frames;
while (skip != 0)
{
output->audio_buffer += *output->audio_length;
output->audio_length ++;
skip --;
}
unsigned int i = 0;
for (; i < output->number_of_audio_frames; i++)
{
if (output->audio_length[i] == 0)
{
output->audio_buffer = 0;
}
}
return(0);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -