kopia lustrzana https://github.com/F5OEO/tstools
135 wiersze
5.8 KiB
C
135 wiersze
5.8 KiB
C
/*
|
||
* 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_defns
|
||
#define _reverse_defns
|
||
|
||
#include "compat.h"
|
||
#include "es_defns.h"
|
||
|
||
// Since reverse_data refers to h262 and acces_unit datastructures, and
|
||
// *they* refer to reverse_data, we need to break the circular referencing
|
||
// at some point
|
||
typedef struct reverse_data *reverse_data_p;
|
||
#include "h262_defns.h"
|
||
#include "accessunit_defns.h"
|
||
|
||
// ------------------------------------------------------------
|
||
// As the software progresses through the data stream forwards, it remembers
|
||
// the location, size and details for frames that it might want to output in
|
||
// reverse
|
||
struct reverse_data
|
||
{
|
||
int is_h264; // Dealing with H.264 or H.262 data?
|
||
|
||
// To do anything useful, we must then be linked to one or the other
|
||
// type of input context (a union would save 4 bytes, but it doesn't
|
||
// seem worth the bother at the moment).
|
||
h262_context_p h262;
|
||
access_unit_context_p h264;
|
||
|
||
// Information for managing our arrays. `use_seq_offset` will be TRUE
|
||
// for H.262 data, and FALSE for H.264 (MPEG-4/AVC)
|
||
int length; // Number of items in our arrays
|
||
int size; // How big our arrays are
|
||
uint32_t num_pictures; // How many pictures we have
|
||
// Four useful arrays (although the last is not used for H.264 data)
|
||
uint32_t *index; // Which picture this is, counted from the start
|
||
offset_t *start_file; // The start offset of an item in the input file
|
||
int32_t *start_pkt; // and then within the PES packet (if needed)
|
||
int32_t *data_len; // Its length in bytes
|
||
|
||
byte *seq_offset; // For MPEG-2, the offset backwards in the arrays
|
||
// to the nearest earlier sequence header, or 0
|
||
// for a sequence header entry
|
||
byte *afd_byte; // For MPEG-2, the AFD byte current for the picture
|
||
|
||
// @@@ To be added later: for H.264 it's useful to know if a particular
|
||
// entry is an IDR or not. Thus add a ``byte *`` value called something
|
||
// like `is_IDR`, and make it point to `seq_offset`, since that is
|
||
// not used for H.264 data.
|
||
// (as a precursor to this, the code in reverse.c already allocates
|
||
// and extends the seq_offset array whether it is H.262 or H.264 data)
|
||
|
||
// Is our "counting" in `index` going to last long enough? Well, if
|
||
// we assume (worst case) that every picture was remembered in our arrays,
|
||
// then we would have 2**32-1 pictures. At (another worst case) 50 frames
|
||
// per second, that gives us (2**32-1)/50 seconds, which is 85899345
|
||
// seconds (rounded down), or 23860 hours. Which I think should be enough
|
||
// (about two years - yes, that should be enough).
|
||
|
||
// When a function (output_in_reverse_as_XX) is called to output
|
||
// reversed data, the reversal can either start from a specific index,
|
||
// or from the "default", which is the current index. To make this easier,
|
||
// we need to remember the index of the last entry added (which may be
|
||
// less than the length of the array, since we might have rewound, and
|
||
// be adding pictures again). Note that this is undefined if `length`
|
||
// is 0.
|
||
//
|
||
// (There's probably a better name for this, since it's really more
|
||
// like the highwater mark for what we've played forwards since we last
|
||
// started playing forwards again, but I can't think of anything startlingly
|
||
// illustrative, so this name will stay for now.)
|
||
uint32_t last_posn_added;
|
||
|
||
// Do we want to output sequence headers or not, when reversing H.262?
|
||
int output_sequence_headers;
|
||
|
||
// If we're outputting TS packets, we need to know the PID and stream id
|
||
// to use. We *could* pass that down to each reverse call, but it's easier
|
||
// to set it once and for all.
|
||
uint32_t pid;
|
||
byte stream_id;
|
||
|
||
// When a function (output_in_reverse_as_XX) is called to output
|
||
// reversed data, some statistics are maintained by the call.
|
||
// Despite saying "picture", these also apply to H.264 access units as well
|
||
// (and in fact "frame" would be a better term).
|
||
int pictures_written; // The number of pictures written out
|
||
int pictures_kept; // The number of *different* pictures written
|
||
int first_written; // Which picture was the first written out
|
||
int last_written; // Which picture was the last written out
|
||
// (for both of the latter, the value is the index of said picture in
|
||
// our arrays). Remember that if forwards action is to be made after
|
||
// reversing, it is important to reset the picture index in the H.262
|
||
// or access_unit context to the picture index of the last written
|
||
// picture. This must be done by the caller.
|
||
};
|
||
#define SIZEOF_REVERSE_DATA sizeof(struct reverse_data)
|
||
|
||
#define REVERSE_ARRAY_START_SIZE 1000
|
||
#define REVERSE_ARRAY_INCREMENT_SIZE 500
|
||
|
||
#endif // _reverse_defns
|
||
|
||
// Local Variables:
|
||
// tab-width: 8
|
||
// indent-tabs-mode: nil
|
||
// c-basic-offset: 2
|
||
// End:
|
||
// vim: set tabstop=8 shiftwidth=2 expandtab:
|