mirror of
https://gitlab.com/mbunkus/mkvtoolnix.git
synced 2024-12-24 03:42:53 +00:00
Merged 1571.
This commit is contained in:
parent
51ced57715
commit
484b0c2fd9
@ -177,14 +177,14 @@ typedef struct rmff_file_t {
|
||||
mb_file_io_t *io;
|
||||
void *handle;
|
||||
char *name;
|
||||
int open_mode;
|
||||
int64_t size;
|
||||
|
||||
int headers_read;
|
||||
|
||||
rmff_prop_t prop_header;
|
||||
int prop_header_found;
|
||||
rmff_cont_t cont_header;
|
||||
int cont_header_found;
|
||||
int cont_header_present;
|
||||
int64_t first_data_header_offset;
|
||||
int64_t next_data_header_offset;
|
||||
uint32_t num_packets_in_chunk;
|
||||
@ -269,6 +269,7 @@ void rmff_close_file(rmff_file_t *file);
|
||||
int rmff_read_headers(rmff_file_t *file);
|
||||
|
||||
/** \brief Retrieves the size of the next frame.
|
||||
*
|
||||
* \param file The file to read from.
|
||||
* \returns the size of the following frame or one of the \c RMFF_ERR_*
|
||||
* constants on error.
|
||||
@ -277,6 +278,7 @@ int rmff_get_next_frame_size(rmff_file_t *file);
|
||||
|
||||
/** \brief Reads the next frame from the file.
|
||||
* The frame must be released by rmff_release_frame(rmff_frame_t*).
|
||||
*
|
||||
* \param file The file to read from.
|
||||
* \param buffer A buffer to read the frame into. This parameter may be
|
||||
* \c NULL in which case the buffer will be allocated by the library.
|
||||
@ -290,11 +292,26 @@ rmff_frame_t *rmff_read_next_frame(rmff_file_t *file, void *buffer);
|
||||
|
||||
/** \brief Frees all resources associated with a frame.
|
||||
* If the frame buffer was allocated by the library it will be freed as well.
|
||||
*
|
||||
* \param frame The frame to free.
|
||||
*/
|
||||
void rmff_release_frame(rmff_frame_t *frame);
|
||||
|
||||
|
||||
/** \brief Sets the contents of the CONT file header.
|
||||
* Frees the old contents if any and allocates copies of the given
|
||||
* strings. If the CONT header should be written to the file
|
||||
* in rmff_write_headers(rmff_file_t*) then the \c cont_header_found
|
||||
* member must be set to 1.
|
||||
*
|
||||
* \param file The file whose CONT header should be set.
|
||||
* \param title The file's title, e.g. "Muriel's Wedding"
|
||||
* \param author The file's author, e.g. "P.J. Hogan"
|
||||
* \param copyright The copyright assigned to the file.
|
||||
* \param comment A free-style comment.
|
||||
*/
|
||||
void rmff_set_cont_header(rmff_file_t *file, const char *title,
|
||||
const char *author, const char *copyright,
|
||||
const char *comment);
|
||||
|
||||
/** \brief The error code of the last function call.
|
||||
* Contains the last error code for a function that failed. If a function
|
||||
|
113
librmff/rmff.c
113
librmff/rmff.c
@ -242,35 +242,20 @@ _saferealloc(void *mem,
|
||||
return mem;
|
||||
}
|
||||
|
||||
rmff_file_t *
|
||||
rmff_open_file(const char *path,
|
||||
int mode) {
|
||||
return rmff_open_file_with_io(path, mode, &std_mb_file_io);
|
||||
}
|
||||
|
||||
rmff_file_t *
|
||||
rmff_open_file_with_io(const char *path,
|
||||
int mode,
|
||||
mb_file_io_t *io) {
|
||||
static rmff_file_t *
|
||||
open_file_for_reading(const char *path,
|
||||
mb_file_io_t *io) {
|
||||
rmff_file_t *file;
|
||||
void *file_h;
|
||||
char buf[5];
|
||||
char signature[5];
|
||||
|
||||
if ((path == NULL) || (io == NULL) ||
|
||||
((mode != RMFF_OPEN_MODE_READING) && (mode != RMFF_OPEN_MODE_WRITING)))
|
||||
return (rmff_file_t *)set_error(RMFF_ERR_PARAMETERS, NULL, 0);
|
||||
|
||||
if (mode == RMFF_OPEN_MODE_READING)
|
||||
mode = MB_OPEN_MODE_READING;
|
||||
else
|
||||
mode = MB_OPEN_MODE_WRITING;
|
||||
file_h = io->open(path, mode);
|
||||
file_h = io->open(path, MB_OPEN_MODE_READING);
|
||||
if (file_h == NULL)
|
||||
return NULL;
|
||||
|
||||
buf[4] = 0;
|
||||
if ((io->read(file_h, buf, 4) != 4) ||
|
||||
strcmp(buf, ".RMF")) {
|
||||
signature[4] = 0;
|
||||
if ((io->read(file_h, signature, 4) != 4) ||
|
||||
strcmp(signature, ".RMF")) {
|
||||
io->close(file_h);
|
||||
return (rmff_file_t *)set_error(RMFF_ERR_NOT_RMFF, NULL, 0);
|
||||
}
|
||||
@ -282,10 +267,57 @@ rmff_open_file_with_io(const char *path,
|
||||
io->seek(file_h, 0, SEEK_END);
|
||||
file->size = io->tell(file_h);
|
||||
io->seek(file_h, 4, SEEK_SET);
|
||||
file->open_mode = RMFF_OPEN_MODE_READING;
|
||||
|
||||
return file;
|
||||
}
|
||||
|
||||
static rmff_file_t *
|
||||
open_file_for_writing(const char *path,
|
||||
mb_file_io_t *io) {
|
||||
rmff_file_t *file;
|
||||
void *file_h;
|
||||
const char *signature = ".RMF";
|
||||
|
||||
file_h = io->open(path, MB_OPEN_MODE_WRITING);
|
||||
if (file_h == NULL)
|
||||
return NULL;
|
||||
|
||||
if (io->write(file_h, signature, 4) != 4) {
|
||||
io->close(file_h);
|
||||
return (rmff_file_t *)set_error(RMFF_ERR_IO, NULL, 0);
|
||||
}
|
||||
|
||||
file = (rmff_file_t *)safecalloc(sizeof(rmff_file_t));
|
||||
file->handle = file_h;
|
||||
file->name = safestrdup(path);
|
||||
file->io = io;
|
||||
file->size = -1;
|
||||
file->open_mode = RMFF_OPEN_MODE_WRITING;
|
||||
|
||||
return file;
|
||||
}
|
||||
|
||||
rmff_file_t *
|
||||
rmff_open_file(const char *path,
|
||||
int mode) {
|
||||
return rmff_open_file_with_io(path, mode, &std_mb_file_io);
|
||||
}
|
||||
|
||||
rmff_file_t *
|
||||
rmff_open_file_with_io(const char *path,
|
||||
int mode,
|
||||
mb_file_io_t *io) {
|
||||
if ((path == NULL) || (io == NULL) ||
|
||||
((mode != RMFF_OPEN_MODE_READING) && (mode != RMFF_OPEN_MODE_WRITING)))
|
||||
return (rmff_file_t *)set_error(RMFF_ERR_PARAMETERS, NULL, 0);
|
||||
|
||||
if (mode == RMFF_OPEN_MODE_READING)
|
||||
return open_file_for_reading(path, io);
|
||||
else
|
||||
return open_file_for_writing(path, io);
|
||||
}
|
||||
|
||||
void
|
||||
rmff_free_track_data(rmff_track_t *track) {
|
||||
if (track == NULL)
|
||||
@ -330,8 +362,9 @@ rmff_read_headers(rmff_file_t *file) {
|
||||
rmff_track_t track;
|
||||
real_video_props_t *rvp;
|
||||
real_audio_v4_props_t *ra4p;
|
||||
int prop_header_found;
|
||||
|
||||
if (file == NULL)
|
||||
if ((file == NULL) || (file->open_mode != RMFF_OPEN_MODE_READING))
|
||||
return set_error(RMFF_ERR_PARAMETERS, NULL, RMFF_ERR_PARAMETERS);
|
||||
if (file->headers_read)
|
||||
return 0;
|
||||
@ -347,6 +380,7 @@ rmff_read_headers(rmff_file_t *file) {
|
||||
skip(4); /* num_headers */
|
||||
|
||||
prop = &file->prop_header;
|
||||
prop_header_found = 0;
|
||||
cont = &file->cont_header;
|
||||
while (1) {
|
||||
rmff_last_error = RMFF_ERR_OK;
|
||||
@ -368,10 +402,10 @@ rmff_read_headers(rmff_file_t *file) {
|
||||
read_uint32_be_to(&prop->data_offset);
|
||||
read_uint16_be_to(&prop->num_streams);
|
||||
read_uint16_be_to(&prop->flags);
|
||||
file->prop_header_found = 1;
|
||||
prop_header_found = 1;
|
||||
|
||||
} else if (object_id == rmffFOURCC('C', 'O', 'N', 'T')) {
|
||||
if (file->cont_header_found) {
|
||||
if (file->cont_header_present) {
|
||||
safefree(cont->title);
|
||||
safefree(cont->author);
|
||||
safefree(cont->copyright);
|
||||
@ -399,7 +433,7 @@ rmff_read_headers(rmff_file_t *file) {
|
||||
cont->comment = (char *)safemalloc(size + 1);
|
||||
io->read(fh, cont->comment, size);
|
||||
}
|
||||
file->cont_header_found = 1;
|
||||
file->cont_header_present = 1;
|
||||
|
||||
} else if (object_id == rmffFOURCC('M', 'D', 'P', 'R')) {
|
||||
memset(&track, 0, sizeof(rmff_track_t));
|
||||
@ -464,7 +498,7 @@ rmff_read_headers(rmff_file_t *file) {
|
||||
}
|
||||
}
|
||||
|
||||
if (file->prop_header_found && (file->first_data_header_offset > 0)) {
|
||||
if (prop_header_found && (file->first_data_header_offset > 0)) {
|
||||
file->headers_read = 1;
|
||||
return 0;
|
||||
}
|
||||
@ -481,7 +515,7 @@ rmff_get_next_frame_size(rmff_file_t *file) {
|
||||
int64_t old_pos;
|
||||
|
||||
if ((file == NULL) || (!file->headers_read) || (file->io == NULL) ||
|
||||
(file->handle == NULL))
|
||||
(file->handle == NULL) || (file->open_mode != RMFF_OPEN_MODE_READING))
|
||||
return set_error(RMFF_ERR_PARAMETERS, NULL, RMFF_ERR_PARAMETERS);
|
||||
io = file->io;
|
||||
fh = file->handle;
|
||||
@ -514,7 +548,7 @@ rmff_read_next_frame(rmff_file_t *file,
|
||||
void *fh;
|
||||
|
||||
if ((file == NULL) || (!file->headers_read) || (file->io == NULL) ||
|
||||
(file->handle == NULL))
|
||||
(file->handle == NULL) || (file->open_mode != RMFF_OPEN_MODE_READING))
|
||||
return (rmff_frame_t *)set_error(RMFF_ERR_PARAMETERS, NULL, 0);
|
||||
io = file->io;
|
||||
fh = file->handle;
|
||||
@ -562,3 +596,22 @@ rmff_release_frame(rmff_frame_t *frame) {
|
||||
safefree(frame->data);
|
||||
safefree(frame);
|
||||
}
|
||||
|
||||
void
|
||||
rmff_set_cont_header(rmff_file_t *file,
|
||||
const char *title,
|
||||
const char *author,
|
||||
const char *copyright,
|
||||
const char *comment) {
|
||||
if (file == NULL)
|
||||
return;
|
||||
|
||||
safefree(file->cont_header.title);
|
||||
safefree(file->cont_header.author);
|
||||
safefree(file->cont_header.copyright);
|
||||
safefree(file->cont_header.comment);
|
||||
file->cont_header.title = safestrdup(title);
|
||||
file->cont_header.author = safestrdup(author);
|
||||
file->cont_header.copyright = safestrdup(copyright);
|
||||
file->cont_header.comment = safestrdup(comment);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user