2008-04-14 04:09:29 +00:00
|
|
|
|
/*
|
|
|
|
|
* Support for reversing
|
|
|
|
|
*
|
|
|
|
|
* ***** BEGIN LICENSE BLOCK *****
|
|
|
|
|
* Version: MPL 1.1
|
|
|
|
|
*
|
|
|
|
|
* The contents of this file are subject to the Mozilla Public License Version
|
|
|
|
|
* 1.1 (the "License"); you may not use this file except in compliance with
|
|
|
|
|
* the License. You may obtain a copy of the License at
|
|
|
|
|
* http://www.mozilla.org/MPL/
|
|
|
|
|
*
|
|
|
|
|
* Software distributed under the License is distributed on an "AS IS" basis,
|
|
|
|
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
|
|
|
|
* for the specific language governing rights and limitations under the
|
|
|
|
|
* License.
|
|
|
|
|
*
|
|
|
|
|
* The Original Code is the MPEG TS, PS and ES tools.
|
|
|
|
|
*
|
|
|
|
|
* The Initial Developer of the Original Code is Amino Communications Ltd.
|
|
|
|
|
* Portions created by the Initial Developer are Copyright (C) 2008
|
|
|
|
|
* the Initial Developer. All Rights Reserved.
|
|
|
|
|
*
|
|
|
|
|
* Contributor(s):
|
|
|
|
|
* Amino Communications Ltd, Swavesey, Cambridge UK
|
|
|
|
|
*
|
|
|
|
|
* ***** END LICENSE BLOCK *****
|
|
|
|
|
*/
|
|
|
|
|
#ifndef _reverse_fns
|
|
|
|
|
#define _reverse_fns
|
|
|
|
|
|
|
|
|
|
#include "accessunit_defns.h"
|
|
|
|
|
#include "reverse_defns.h"
|
|
|
|
|
#include "h262_defns.h"
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Build the internal arrays to remember video sequence bounds in,
|
|
|
|
|
* for reversing.
|
|
|
|
|
*
|
|
|
|
|
* Builds a new `reverse_data` datastructure. If `is_h264` is FALSE (i.e., the
|
|
|
|
|
* data to be reversed is not MPEG-1 or MPEG-2), then this datastructure may
|
|
|
|
|
* be smaller.
|
|
|
|
|
*
|
|
|
|
|
* To collect reversing data, attach this datastructure to an H.262 or access
|
|
|
|
|
* unit context (with add_h262/access_unit_reverse_context), and then use
|
|
|
|
|
* get_next_h262_frame() or get_next_h264_frame() to read through the data
|
|
|
|
|
* stream - appropriate pictures/access units will be remembered
|
|
|
|
|
* automatically.
|
|
|
|
|
*
|
|
|
|
|
* Returns 0 if it succeeds, 1 if some error occurs.
|
|
|
|
|
*/
|
|
|
|
|
extern int build_reverse_data(reverse_data_p *reverse_data,
|
|
|
|
|
int is_h264);
|
|
|
|
|
/*
|
|
|
|
|
* Set the video PID and stream id for TS output.
|
|
|
|
|
*
|
|
|
|
|
* This need only be called if reverse data *is* being output as TS,
|
|
|
|
|
* and if the standard default values (DEFAULT_VIDEO_PID and
|
|
|
|
|
* DEFAULT_VIDEO_STREAM_ID) are not correct.
|
|
|
|
|
*/
|
|
|
|
|
extern void set_reverse_pid(reverse_data_p reverse_data,
|
2008-10-18 15:04:34 +00:00
|
|
|
|
uint32_t pid,
|
2008-04-14 04:09:29 +00:00
|
|
|
|
byte stream_id);
|
|
|
|
|
/*
|
|
|
|
|
* Add a reversing context to an H.262 context (and vice versa).
|
|
|
|
|
*
|
|
|
|
|
* Does not check if there is one present already.
|
|
|
|
|
*
|
|
|
|
|
* Returns 0 if all is well, 1 if something goes wrong.
|
|
|
|
|
*/
|
|
|
|
|
extern int add_h262_reverse_context(h262_context_p h262,
|
|
|
|
|
reverse_data_p reverse_data);
|
|
|
|
|
/*
|
|
|
|
|
* Add a reversing context to an access unit context (and vice versa).
|
|
|
|
|
*
|
|
|
|
|
* Does not check if there is one present already.
|
|
|
|
|
*
|
|
|
|
|
* Returns 0 if all is well, 1 if something goes wrong.
|
|
|
|
|
*/
|
|
|
|
|
extern int add_access_unit_reverse_context(access_unit_context_p context,
|
|
|
|
|
reverse_data_p reverse_data);
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Free the datastructure we used to remember reversing data
|
|
|
|
|
*
|
|
|
|
|
* Sets `reverse_data` to NULL.
|
|
|
|
|
*/
|
|
|
|
|
extern void free_reverse_data(reverse_data_p *reverse_data);
|
|
|
|
|
/*
|
|
|
|
|
* Remember video sequence bounds for H.262 data
|
|
|
|
|
*
|
|
|
|
|
* - `reverse_data` is the datastructure we want to add our entry to
|
|
|
|
|
* - `index` indicates which picture (counted from the start of the file)
|
|
|
|
|
* this one is (i.e., we're assuming that not all pictures will be stored).
|
|
|
|
|
* If the entry is an H.262 sequence header, then this is ignored.
|
|
|
|
|
* - `start_posn` is the location of the start of the entry in the file,
|
|
|
|
|
* The entry will be ignored if `start_posn` comes before the last
|
|
|
|
|
* existing entry in the arrays.
|
|
|
|
|
* - `length` is the number of bytes in the entry
|
|
|
|
|
* - in H.262 data, `seq_offset` should be 0 for a sequence header, and is
|
|
|
|
|
* otherwise the offset backwards to the previous nearest sequence header
|
|
|
|
|
* (i.e., 1 if the sequence header is the previous entry).
|
|
|
|
|
* - `afd` is the effective AFD byte for this picture
|
|
|
|
|
*
|
|
|
|
|
* Returns 0 if it succeeds, 1 if some error occurs.
|
|
|
|
|
*/
|
|
|
|
|
extern int remember_reverse_h262_data(reverse_data_p reverse_data,
|
2008-10-18 15:04:34 +00:00
|
|
|
|
uint32_t index,
|
2008-04-14 04:09:29 +00:00
|
|
|
|
ES_offset start_posn,
|
2008-10-18 15:04:34 +00:00
|
|
|
|
uint32_t length,
|
2008-04-14 04:09:29 +00:00
|
|
|
|
byte seq_offset,
|
|
|
|
|
byte afd);
|
|
|
|
|
/*
|
|
|
|
|
* Remember video sequence bounds for H.264 data
|
|
|
|
|
*
|
|
|
|
|
* - `reverse_data` is the datastructure we want to add our entry to
|
|
|
|
|
* - `index` indicates which picture (counted from the start of the file)
|
|
|
|
|
* this one is (i.e., we're assuming that not all pictures will be stored).
|
|
|
|
|
* If the entry is an H.262 sequence header, then this is ignored.
|
|
|
|
|
* - `start_posn` is the location of the start of the entry in the file,
|
|
|
|
|
* The entry will be ignored if `start_posn` comes before the last
|
|
|
|
|
* existing entry in the arrays.
|
|
|
|
|
* - `length` is the number of bytes in the entry
|
|
|
|
|
*
|
|
|
|
|
* Returns 0 if it succeeds, 1 if some error occurs.
|
|
|
|
|
*/
|
|
|
|
|
extern int remember_reverse_h264_data(reverse_data_p reverse_data,
|
2008-10-18 15:04:34 +00:00
|
|
|
|
uint32_t index,
|
2008-04-14 04:09:29 +00:00
|
|
|
|
ES_offset start_posn,
|
2008-10-18 15:04:34 +00:00
|
|
|
|
uint32_t length);
|
2008-04-14 04:09:29 +00:00
|
|
|
|
/*
|
|
|
|
|
* Retrieve video sequence bounds for entry `which`
|
|
|
|
|
*
|
|
|
|
|
* - `reverse_data` is the datastructure we want to get our entry from
|
|
|
|
|
* - `which` indicates which entry we'd like to retrieve. The first
|
|
|
|
|
* entry in the `reverse_data` is number 0.
|
|
|
|
|
* - `index` indicates which picture (counted from the start of the file)
|
|
|
|
|
* this one is (i.e., we're assuming that not all pictures will be stored).
|
|
|
|
|
* `index` may be passed as NULL if the value is of no interest - i.e.,
|
|
|
|
|
* typically when the entry is for an H.262 sequence header.
|
|
|
|
|
* - `start_posn` is the location of the start of the entry in the file,
|
|
|
|
|
* - `length` is the number of bytes in the entry
|
|
|
|
|
* - for H.262 data, if the entry is a picture, then `seq_offset` will
|
|
|
|
|
* be the offset backwards to the previous nearest sequence header
|
|
|
|
|
* (i.e., 1 if the sequence header is the previous entry), and if it is
|
|
|
|
|
* a sequence header, `seq_offset` will be 0. For H.264 data, the value
|
|
|
|
|
* will always be 0. `seq_offset` may be passed as NULL if the value is
|
|
|
|
|
* of no interest.
|
|
|
|
|
* - for H.262 data, if the entry is a picture, then `afd` will be its
|
|
|
|
|
* (effective) AFD byte. Otherwise it will be 0. `afd` may be passed as NULL
|
|
|
|
|
* if the value if of no interest.
|
|
|
|
|
*
|
|
|
|
|
* To clarify, all of the following are legitimate calls::
|
|
|
|
|
*
|
|
|
|
|
* err = get_reverse_data(reverse_data,10,&index,&start,&length,&offset,&afd);
|
|
|
|
|
* err = get_reverse_data(reverse_data,10,&index,&start,&length,NULL,NULL);
|
|
|
|
|
* err = get_reverse_data(reverse_data,10,NULL,&start,&length,NULL,NULL);
|
|
|
|
|
*
|
|
|
|
|
* Returns 0 if it succeeds, 1 if some error occurs.
|
|
|
|
|
*/
|
|
|
|
|
extern int get_reverse_data(reverse_data_p reverse_data,
|
|
|
|
|
int which,
|
2008-10-18 15:04:34 +00:00
|
|
|
|
uint32_t *index,
|
2008-04-14 04:09:29 +00:00
|
|
|
|
ES_offset *start_posn,
|
2008-10-18 15:04:34 +00:00
|
|
|
|
uint32_t *length,
|
2008-04-14 04:09:29 +00:00
|
|
|
|
byte *seq_offset,
|
|
|
|
|
byte *afd);
|
|
|
|
|
|
|
|
|
|
// ============================================================
|
|
|
|
|
// Collecting pictures
|
|
|
|
|
// ============================================================
|
|
|
|
|
/*
|
|
|
|
|
* Locate and remember sequence headers and I pictures, for later reversal.
|
|
|
|
|
*
|
|
|
|
|
* - `h262` is the H.262 stream reading context
|
|
|
|
|
* - if `max` is non-zero, then collecting will stop after `max` pictures
|
|
|
|
|
* - if `verbose` is true, then extra information will be output
|
|
|
|
|
* - if `quiet` is true, then only errors will be reported
|
|
|
|
|
*
|
|
|
|
|
* Returns 0 if all went well, EOF if the end of file is reached,
|
|
|
|
|
* and 1 if an error occurred.
|
|
|
|
|
*
|
|
|
|
|
* If command input is enabled, then it can also return COMMAND_RETURN_CODE
|
|
|
|
|
* if the current command has changed.
|
|
|
|
|
*/
|
|
|
|
|
extern int collect_reverse_h262(h262_context_p h262,
|
|
|
|
|
int max,
|
|
|
|
|
int verbose,
|
|
|
|
|
int quiet);
|
|
|
|
|
/*
|
|
|
|
|
* Find IDR and I slices, and remember their access units for later output
|
|
|
|
|
* in reverse order.
|
|
|
|
|
*
|
|
|
|
|
* - `acontext` is the access unit reading context
|
|
|
|
|
* - if `max` is non-zero, then collecting will stop after `max` access units
|
|
|
|
|
* - if `verbose` is true, then extra information will be output
|
|
|
|
|
* - if `quiet` is true, then only errors will be reported
|
|
|
|
|
*
|
|
|
|
|
* Returns 0 if all went well, EOF if the end of file is reached,
|
|
|
|
|
* and 1 if an error occurred.
|
|
|
|
|
*
|
|
|
|
|
* If command input is enabled, then it can also return COMMAND_RETURN_CODE
|
|
|
|
|
* if the current command has changed.
|
|
|
|
|
*/
|
|
|
|
|
extern int collect_reverse_access_units(access_unit_context_p acontext,
|
|
|
|
|
int max,
|
|
|
|
|
int verbose,
|
|
|
|
|
int quiet);
|
|
|
|
|
/*
|
|
|
|
|
* Output the last picture (or an earlier one) from the reverse arrays.
|
|
|
|
|
* This version writes the data out as Transport Stream.
|
|
|
|
|
*
|
|
|
|
|
* This is expected to be used after the whole of the data stream has been
|
|
|
|
|
* played, so that the last picture in the reverse arrays is the last I or
|
|
|
|
|
* IDR picture in the data stream.
|
|
|
|
|
*
|
|
|
|
|
* - `es` is the input elementary stream
|
|
|
|
|
* - `tswriter` is the transport stream writer
|
|
|
|
|
* - if `verbose` is true, then extra information will be output
|
|
|
|
|
* - if `quiet` is true, then only errors will be reported
|
|
|
|
|
* - `offset` is the offset from the end of the array of the picture
|
|
|
|
|
* to output - so 0 means the last picture, 1 the picture before that,
|
|
|
|
|
* and so on. Sequence headers do not count for this purpose.
|
|
|
|
|
* - `reverse_data` is the reverse data context.
|
|
|
|
|
*
|
|
|
|
|
* Returns 0 if all went well, 1 if an error occurred.
|
|
|
|
|
*
|
|
|
|
|
* If command input is enabled, then it can also return COMMAND_RETURN_CODE
|
|
|
|
|
* if the current command has changed.
|
|
|
|
|
*/
|
|
|
|
|
extern int output_from_reverse_data_as_TS(ES_p es,
|
|
|
|
|
TS_writer_p tswriter,
|
|
|
|
|
int verbose,
|
|
|
|
|
int quiet,
|
2008-10-18 15:04:34 +00:00
|
|
|
|
uint32_t offset,
|
2008-04-14 04:09:29 +00:00
|
|
|
|
reverse_data_p reverse_data);
|
|
|
|
|
/*
|
|
|
|
|
* Output the last picture (or an earlier one) from the reverse arrays.
|
|
|
|
|
* This version writes the data out as Elementary Stream.
|
|
|
|
|
*
|
|
|
|
|
* This is expected to be used after the whole of the data stream has been
|
|
|
|
|
* played, so that the last picture in the reverse arrays is the last I or
|
|
|
|
|
* IDR picture in the data stream.
|
|
|
|
|
*
|
|
|
|
|
* - `es` is the input elementary stream
|
|
|
|
|
* - `output` is the stream to write to
|
|
|
|
|
* - if `verbose` is true, then extra information will be output
|
|
|
|
|
* - if `quiet` is true, then only errors will be reported
|
|
|
|
|
* - `offset` is the offset from the end of the array of the picture
|
|
|
|
|
* to output - so 0 means the last picture, 1 the picture before that,
|
|
|
|
|
* and so on. Sequence headers do not count for this purpose.
|
|
|
|
|
* - `reverse_data` is the reverse data context.
|
|
|
|
|
*
|
|
|
|
|
* Returns 0 if all went well, 1 if an error occurred.
|
|
|
|
|
*
|
|
|
|
|
* If command input is enabled, then it can also return COMMAND_RETURN_CODE
|
|
|
|
|
* if the current command has changed.
|
|
|
|
|
*/
|
|
|
|
|
extern int output_from_reverse_data_as_ES(ES_p es,
|
|
|
|
|
FILE *output,
|
|
|
|
|
int verbose,
|
|
|
|
|
int quiet,
|
2008-10-18 15:04:34 +00:00
|
|
|
|
uint32_t offset,
|
2008-04-14 04:09:29 +00:00
|
|
|
|
reverse_data_p reverse_data);
|
|
|
|
|
/*
|
|
|
|
|
* Output the H.262 pictures or H.264 access units we remembered earlier - but
|
|
|
|
|
* in reverse order. This version writes the data out as Transport Stream.
|
|
|
|
|
*
|
|
|
|
|
* - `es` is the input elementary stream
|
|
|
|
|
* - `tswriter` is the transport stream writer
|
|
|
|
|
* - if `frequency` is non-zero, then attempt to produce the effect of
|
|
|
|
|
* keeping every <frequency>th picture (similar to reversing at a
|
|
|
|
|
* multiplication factor of `frequency`) If 0, just output all the
|
|
|
|
|
* pictures that were remembered.
|
|
|
|
|
* - if `verbose` is true, then extra information will be output
|
|
|
|
|
* - if `quiet` is true, then only errors will be reported
|
|
|
|
|
* - `start_with` is the index at which to start outputting from the
|
|
|
|
|
* reverse data arrays. The value -1 may be used to indicate the most
|
|
|
|
|
* recent picture in the arrays. If `start_with` is less than -1 then this
|
|
|
|
|
* function will do nothing. If `start_with` is off the end of the
|
|
|
|
|
* arrays, then reversing will start from the end of the arrays.
|
|
|
|
|
* - if `max` is non-zero, then output will stop after at least `max`
|
|
|
|
|
* pictures have been reversed past.
|
|
|
|
|
* - `reverse_data` contains the list of pictures/access units to reverse.
|
|
|
|
|
*
|
|
|
|
|
* Returns 0 if all went well, 1 if an error occurred.
|
|
|
|
|
*
|
|
|
|
|
* If command input is enabled, then it can also return COMMAND_RETURN_CODE
|
|
|
|
|
* if the current command has changed.
|
|
|
|
|
*/
|
|
|
|
|
extern int output_in_reverse_as_TS(ES_p es,
|
|
|
|
|
TS_writer_p tswriter,
|
|
|
|
|
int frequency,
|
|
|
|
|
int verbose,
|
|
|
|
|
int quiet,
|
2008-10-18 15:04:34 +00:00
|
|
|
|
int32_t start_with,
|
2008-04-14 04:09:29 +00:00
|
|
|
|
int max,
|
|
|
|
|
reverse_data_p reverse_data);
|
|
|
|
|
/*
|
|
|
|
|
* Output the H.262 pictures or H.264 access units we remembered earlier - but
|
|
|
|
|
* in reverse order. This version writes the data out as Elementary Stream.
|
|
|
|
|
*
|
|
|
|
|
* - `es` is the input elementary stream
|
|
|
|
|
* - `output` is the stream to write to
|
|
|
|
|
* - if `frequency` is non-zero, then attempt to produce the effect of
|
|
|
|
|
* keeping every <frequency>th picture (similar to reversing at a
|
|
|
|
|
* multiplication factor of `frequency`) If 0, just output all the
|
|
|
|
|
* pictures that were remembered.
|
|
|
|
|
* - if `verbose` is true, then extra information will be output
|
|
|
|
|
* - if `quiet` is true, then only errors will be reported
|
|
|
|
|
* - `start_with` is the index at which to start outputting from the
|
|
|
|
|
* reverse data arrays. The value -1 may be used to indicate the most
|
|
|
|
|
* recent in the arrays. If `start_with` is less than -1 then this
|
|
|
|
|
* function will do nothing. If `start_with` is off the end of the
|
|
|
|
|
* arrays, then reversing will start from the end of the arrays.
|
|
|
|
|
* - if `max` is non-zero, then output will stop after at least `max`
|
|
|
|
|
* pictures have been reversed past.
|
|
|
|
|
* - `reverse_data` contains the list of pictures/access units to reverse.
|
|
|
|
|
*
|
|
|
|
|
* Returns 0 if all went well, 1 if an error occurred.
|
|
|
|
|
*
|
|
|
|
|
* If command input is enabled, then it can also return COMMAND_RETURN_CODE
|
|
|
|
|
* if the current command has changed.
|
|
|
|
|
*/
|
|
|
|
|
extern int output_in_reverse_as_ES(ES_p es,
|
|
|
|
|
FILE *output,
|
|
|
|
|
int frequency,
|
|
|
|
|
int verbose,
|
|
|
|
|
int quiet,
|
2008-10-18 15:04:34 +00:00
|
|
|
|
int32_t start_with,
|
2008-04-14 04:09:29 +00:00
|
|
|
|
int max,
|
|
|
|
|
reverse_data_p reverse_data);
|
|
|
|
|
|
|
|
|
|
#endif // _reverse_fns
|
2008-06-14 16:05:00 +00:00
|
|
|
|
|
|
|
|
|
// Local Variables:
|
|
|
|
|
// tab-width: 8
|
|
|
|
|
// indent-tabs-mode: nil
|
|
|
|
|
// c-basic-offset: 2
|
|
|
|
|
// End:
|
|
|
|
|
// vim: set tabstop=8 shiftwidth=2 expandtab:
|