F5OEO-tstools/accessunit_fns.h

305 wiersze
12 KiB
C
Czysty Zwykły widok Historia

/*
* Functions for working with access units in H.264 elementary streams.
*
* ***** 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 _accessunit_fns
#define _accessunit_fns
#include "accessunit_defns.h"
/*
* Build a new access unit context datastructure.
*
* Returns 0 if it succeeds, 1 if some error occurs.
*/
extern int build_access_unit_context(ES_p es,
access_unit_context_p *context);
/*
* Free a new access unit context datastructure.
*
* Clears the datastructure, frees it, and returns `context` as NULL.
*
* Does not free any `reverse_data` datastructure.
*
* Does nothing if `context` is already NULL.
*/
extern void free_access_unit_context(access_unit_context_p *context);
/*
* Reset an acccess unit context, so it "forgets" its current information
* about what it is reading, etc.
*/
extern void reset_access_unit_context(access_unit_context_p context);
/*
* Rewind a file being read as access units.
*
* This is a wrapper for `rewind_nal_unit_context` that also knows to
* unset things appropriate to the access unit context.
*
* If a reverse context is attached to this access unit, it also will
* be "rewound" appropriately.
*
* Returns 0 if all goes well, 1 if something goes wrong.
*/
extern int rewind_access_unit_context(access_unit_context_p context);
/*
* Tidy up and free an access unit datastructure after we've finished with it.
*
* Clears the datastructure, frees it, and returns `acc_unit` as NULL.
*
* Does nothing if `acc_unit` is already NULL.
*/
extern void free_access_unit(access_unit_p *acc_unit);
/*
* Report on this access unit
*/
extern void report_access_unit(access_unit_p access_unit);
/*
* Retrieve the bounds of this access unit in the file it was read from.
*
* - `access_unit` is the access unit we're interested in
* - `start` is its start position (i.e., the location at which to start
* reading to retrieve all of the data for the access unit, including
* the 00 00 01 prefix at the start of the first NAL unit therein)
* - `length` is the total length of the NAL units within this access unit
*
* Returns 0 if all goes well, 1 if the access unit has no content.
*/
extern int get_access_unit_bounds(access_unit_p access_unit,
ES_offset *start,
uint32_t *length);
/*
* Are all slices in this access unit I slices?
*/
extern int all_slices_I(access_unit_p access_unit);
/*
* Are all slices in this access unit P slices?
*/
extern int all_slices_P(access_unit_p access_unit);
/*
* Are all slices in this access unit I or P slices?
*/
extern int all_slices_I_or_P(access_unit_p access_unit);
/*
* Are all slices in this access unit B slices?
*/
extern int all_slices_B(access_unit_p access_unit);
/*
* Write out an access unit as ES.
*
* Also writes out any end of sequence or end of stream NAL unit found in the
* `context` (since they are assumed to have immediately followed this access
* unit).
*
* - `access_unit` is the access unit to write out
* - `context` may contain additional things to write (see above), but may
* legitimately be NULL if there is no context.
* - `output` is the ES file to write to
*
* Returns 0 if it succeeds, 1 if some error occurs.
*/
extern int write_access_unit_as_ES(access_unit_p access_unit,
access_unit_context_p context,
FILE *output);
/*
* Write out an access unit as TS.
*
* Also writes out any end of sequence or end of stream NAL unit found in the
* `context` (since they are assumed to have immediately followed this access
* unit).
*
* - `access_unit` is the access unit to write out
* - `context` may contain additional things to write (see above), but may
* legitimately be NULL if there is no context.
* - `tswriter` is the TS context to write with
* - `video_pid` is the PID to use to write the data
*
* Returns 0 if it succeeds, 1 if some error occurs.
*/
extern int write_access_unit_as_TS(access_unit_p access_unit,
access_unit_context_p context,
TS_writer_p tswriter,
uint32_t video_pid);
/*
* Write out an access unit as TS, with PTS timing in the first PES packet
* (and PCR timing in the first TS of the frame).
*
* Also writes out any end of sequence or end of stream NAL unit found in the
* `context` (since they are assumed to have immediately followed this access
* unit).
*
* - `access_unit` is the access unit to write out
* - `context` may contain additional things to write (see above), but may
* legitimately be NULL if there is no context.
* - `tswriter` is the TS context to write with
* - `video_pid` is the PID to use to write the data
* - `pts` is the PTS time (which is also used as the PCR base).
*
* Returns 0 if it succeeds, 1 if some error occurs.
*/
extern int write_access_unit_as_TS_with_pts_dts(access_unit_p access_unit,
access_unit_context_p context,
TS_writer_p tswriter,
uint32_t video_pid,
int got_pts,
uint64_t pts,
int got_dts,
uint64_t dts);
/*
* Write out an access unit as TS, with PCR timing in the first TS of the
* frame.
*
* Also writes out any end of sequence or end of stream NAL unit found in the
* `context` (since they are assumed to have immediately followed this access
* unit).
*
* - `access_unit` is the access unit to write out
* - `context` may contain additional things to write (see above), but may
* legitimately be NULL if there is no context.
* - `tswriter` is the TS context to write with
* - `video_pid` is the PID to use to write the data
* - `pcr_base` and `pcr_extn` encode the PCR value.
*
* Returns 0 if it succeeds, 1 if some error occurs.
*/
extern int write_access_unit_as_TS_with_PCR(access_unit_p access_unit,
access_unit_context_p context,
TS_writer_p tswriter,
uint32_t video_pid,
uint64_t pcr_base,
uint32_t pcr_extn);
/*
* Retrieve the next access unit from the given elementary stream.
*
* - `context` is the context information needed to allow us to find
* successive access units.
* - `quiet` is true if we should try to be silent about it
* - `show_details` is true if we should output more info than normal
* - `ret_access_unit` is the next access unit.
*
* If the access unit was ended because an end of sequence or end of
* stream NAL unit was encountered, then said end of sequence/stream
* NAL unit will be remembered in the `context`.
*
* Note that it is possible to get back an *empty* access unit in
* certain situations - the most obvious of which is if we get two
* ``end of sequence`` NAL units with nothing betwen them.
*
* Because of this possibility, some care should be taken to allow for
* access units that do not contain a primary picture (no VCL NAL unit),
* and contain zero NAL units. Also, if one is trying for an accurate
* count of access units, such instances should probably be ignored.
*
* Returns 0 if it succeeds, EOF if there is no more data to read, or 1 if
* some error occurs.
*
* EOF can be returned because the end of file has been reached, or because an
* end of stream NAL unit has been encountered. The two may be distinguished
* by looking at `context->end_of_stream`, which will be NULL if it was a true
* EOF.
*
* Note that `ret_access_unit` will be NULL if EOF is returned.
*/
extern int get_next_access_unit(access_unit_context_p context,
int quiet,
int show_details,
access_unit_p *ret_access_unit);
/*
* Retrieve the next H.264 frame from the given elementary stream.
*
* The next access unit is retrieved from the input stream (using
* get_next_access_unit).
*
* If that access unit represents a frame, it is returned.
*
* If it represents a field, then the *following* access unit is retrieved,
* and if that is the second field of its frame, it is merged into the first,
* and the resultant frame is returned.
*
* If a field with frame number A is followed by a field with frame number B,
* it is assumed that synchronisation has been lost. In this case, the first
* field (frame A) will be discarded, and an attempt made to read the second
* field of frame B.
*
* Similarly, if a frame is found instead of the second field, the first
* field will be discarded and the frame returned.
*
* Note that if the context is associated with a reverse context,
* then appropriate frames will automatically be remembered therein.
*
* - `context` is the context information needed to allow us to find
* successive access units.
* - `quiet` is true if we should try to be silent about it
* - `show_details` is true if we should output more info than normal
* - `frame` is an access unit datastructure representing the next
* frame.
*
* If the access unit was ended because an end of sequence or end of
* stream NAL unit was encountered, then said end of sequence/stream
* NAL unit will be remembered in the `context`.
*
* Returns 0 if it succeeds, EOF if there is no more data to read, or 1 if
* some error occurs.
*
* EOF can be returned because the end of file has been reached, or because an
* end of stream NAL unit has been encountered. The two may be distinguished
* by looking at `context->end_of_stream`, which will be NULL if it was a true
* EOF.
*
* Note that `ret_access_unit` will be NULL if EOF is returned.
*/
extern int get_next_h264_frame(access_unit_context_p context,
int quiet,
int show_details,
access_unit_p *frame);
/*
* If this access unit was read from PES, did any of its PES packets contain
* a PTS?
*
* Returns TRUE if so, FALSE if not.
*/
extern int access_unit_has_PTS(access_unit_p access_unit);
#endif // _accessunit_fns
// Local Variables:
// tab-width: 8
// indent-tabs-mode: nil
// c-basic-offset: 2
// End:
// vim: set tabstop=8 shiftwidth=2 expandtab: