76 #define _XOPEN_SOURCE 600 
   81 #include <libcrystalhd/bc_dts_types.h> 
   82 #include <libcrystalhd/bc_dts_defs.h> 
   83 #include <libcrystalhd/libcrystalhd_if.h> 
   97 #define OUTPUT_PROC_TIMEOUT 50 
   99 #define TIMESTAMP_UNIT 100000 
  101 #define BASE_WAIT 10000 
  103 #define WAIT_UNIT 1000 
  156     { 
"crystalhd_downscale_width",
 
  157       "Turn on downscaling to the specified width",
 
  173         return BC_MSUBTYPE_DIVX;
 
  175         return BC_MSUBTYPE_DIVX311;
 
  177         return BC_MSUBTYPE_MPEG2VIDEO;
 
  179         return BC_MSUBTYPE_VC1;
 
  181         return BC_MSUBTYPE_WMV3;
 
  183         return priv->
is_nal ? BC_MSUBTYPE_AVC1 : BC_MSUBTYPE_H264;
 
  185         return BC_MSUBTYPE_INVALID;
 
  193            output->YBuffDoneSz);
 
  195            output->UVBuffDoneSz);
 
  197            output->PicInfo.timeStamp);
 
  199            output->PicInfo.picture_number);
 
  201            output->PicInfo.width);
 
  203            output->PicInfo.height);
 
  205            output->PicInfo.chroma_format);
 
  207            output->PicInfo.pulldown);
 
  209            output->PicInfo.flags);
 
  211            output->PicInfo.frame_rate);
 
  213            output->PicInfo.aspect_ratio);
 
  215            output->PicInfo.colour_primaries);
 
  217            output->PicInfo.picture_meta_payload);
 
  219            output->PicInfo.sess_num);
 
  221            output->PicInfo.ycom);
 
  223            output->PicInfo.custom_aspect_ratio_width_height);
 
  225            output->PicInfo.n_drop);
 
  227            output->PicInfo.other.h264.valid);
 
  241                "Unable to allocate new node in OpaqueList.\n");
 
  246         priv->
head              = newNode;
 
  251     priv->
tail = newNode;
 
  271                "CrystalHD: Attempted to query non-existent timestamps.\n");
 
  309            "CrystalHD: Couldn't match fake_timestamp.\n");
 
  332     DtsFlushInput(priv->
dev, 4);
 
  342     DtsStopDecoder(device);
 
  343     DtsCloseDecoder(device);
 
  344     DtsDeviceClose(device);
 
  386     void *extradata = 
NULL;
 
  392                "Cannot open the %s BSF!\n", bsf_name);
 
  419                "Failed to allocate copy of extradata\n");
 
  436     BC_INPUT_FORMAT 
format = {
 
  439         .OptFlags    = 0x80000000 | vdecFrameRate59_94 | 0x40,
 
  440         .width       = avctx->
width,
 
  444     BC_MEDIA_SUBTYPE subtype;
 
  446     uint32_t 
mode = DTS_PLAYBACK_MODE |
 
  447                     DTS_LOAD_FILE_PLAY_FW |
 
  448                     DTS_SKIP_TX_CHK_CPB |
 
  449                     DTS_PLAYBACK_DROP_RPT_MODE |
 
  450                     DTS_SINGLE_THREADED_MODE |
 
  451                     DTS_DFLT_RESOLUTION(vdecRESOLUTION_1080p23_976);
 
  468     case BC_MSUBTYPE_AVC1:
 
  469         avret = 
init_bsf(avctx, 
"h264_mp4toannexb");
 
  473         subtype = BC_MSUBTYPE_H264;
 
  474         format.startCodeSz = 4;
 
  478     case BC_MSUBTYPE_DIVX:
 
  479         avret = 
init_bsf(avctx, 
"mpeg4_unpack_bframes");
 
  486     case BC_MSUBTYPE_H264:
 
  487         format.startCodeSz = 4;
 
  489     case BC_MSUBTYPE_VC1:
 
  490     case BC_MSUBTYPE_WVC1:
 
  491     case BC_MSUBTYPE_WMV3:
 
  492     case BC_MSUBTYPE_WMVA:
 
  493     case BC_MSUBTYPE_MPEG2VIDEO:
 
  494     case BC_MSUBTYPE_DIVX311:
 
  502     format.mSubtype = subtype;
 
  505         format.bEnableScaling = 1;
 
  506         format.ScalingParams.sWidth = priv->
sWidth;
 
  512     ret = DtsDeviceOpen(&priv->
dev, mode);
 
  513     if (ret != BC_STS_SUCCESS) {
 
  518     ret = DtsCrystalHDVersion(priv->
dev, &version);
 
  519     if (ret != BC_STS_SUCCESS) {
 
  521                "CrystalHD: DtsCrystalHDVersion failed\n");
 
  524     priv->
is_70012 = version.device == 0;
 
  527         (subtype == BC_MSUBTYPE_DIVX || subtype == BC_MSUBTYPE_DIVX311)) {
 
  529                "CrystalHD: BCM70012 doesn't support MPEG4-ASP/DivX/Xvid\n");
 
  533     ret = DtsSetInputFormat(priv->
dev, &format);
 
  534     if (ret != BC_STS_SUCCESS) {
 
  539     ret = DtsOpenDecoder(priv->
dev, BC_STREAM_TYPE_ES);
 
  540     if (ret != BC_STS_SUCCESS) {
 
  545     ret = DtsSetColorSpace(priv->
dev, OUTPUT_MODE422_YUY2);
 
  546     if (ret != BC_STS_SUCCESS) {
 
  550     ret = DtsStartDecoder(priv->
dev);
 
  551     if (ret != BC_STS_SUCCESS) {
 
  555     ret = DtsStartCapture(priv->
dev);
 
  556     if (ret != BC_STS_SUCCESS) {
 
  565                    "Cannot open the h.264 parser! Interlaced h.264 content " 
  566                    "will not be detected reliably.\n");
 
  580                                  BC_DTS_PROC_OUT *output,
 
  581                                  void *
data, 
int *got_frame)
 
  584     BC_DTS_STATUS decoder_status = { 0, };
 
  592     uint8_t bottom_field = (output->PicInfo.flags & VDEC_FLAG_BOTTOMFIELD) ==
 
  593                            VDEC_FLAG_BOTTOMFIELD;
 
  594     uint8_t bottom_first = !!(output->PicInfo.flags & VDEC_FLAG_BOTTOM_FIRST);
 
  596     int width    = output->PicInfo.width;
 
  597     int height   = output->PicInfo.height;
 
  604     if (output->PicInfo.timeStamp != 0) {
 
  622                output->PicInfo.timeStamp);
 
  627     ret = DtsGetDriverStatus(priv->
dev, &decoder_status);
 
  628     if (ret != BC_STS_SUCCESS) {
 
  630                "CrystalHD: GetDriverStatus failed: %u\n", ret);
 
  651                        !(output->PicInfo.flags & VDEC_FLAG_UNKNOWN_SRC) ||
 
  653                        (decoder_status.picNumFlags & ~0x40000000) ==
 
  654                        output->PicInfo.picture_number;
 
  664                "Incorrectly guessed progressive frame. Discarding second field\n");
 
  669     interlaced = (output->PicInfo.flags & VDEC_FLAG_INTERLACED_SRC) &&
 
  672     if (!trust_interlaced && (decoder_status.picNumFlags & ~0x40000000) == 0) {
 
  674                "Next picture number unknown. Assuming progressive frame.\n");
 
  678            interlaced, trust_interlaced);
 
  696         else if (width <= 1280)
 
  722         for (sY = 0; sY < 
height; dY++, sY++) {
 
  723             memcpy(&(dst[dY * dStride]), &(src[sY * sStride]), bwidth);
 
  760     if (!interlaced && (output->PicInfo.flags & VDEC_FLAG_UNKNOWN_SRC) &&
 
  779            (!(output->PicInfo.flags & VDEC_FLAG_UNKNOWN_SRC) ||
 
  786                                     void *
data, 
int *got_frame)
 
  789     BC_DTS_PROC_OUT output = {
 
  790         .PicInfo.width  = avctx->
width,
 
  791         .PicInfo.height = avctx->
height,
 
  800     if (ret == BC_STS_FMT_CHANGE) {
 
  802         avctx->
width  = output.PicInfo.width;
 
  803         avctx->
height = output.PicInfo.height;
 
  804         switch ( output.PicInfo.aspect_ratio ) {
 
  805         case vdecAspectRatioSquare:
 
  808         case vdecAspectRatio12_11:
 
  811         case vdecAspectRatio10_11:
 
  814         case vdecAspectRatio16_11:
 
  817         case vdecAspectRatio40_33:
 
  820         case vdecAspectRatio24_11:
 
  823         case vdecAspectRatio20_11:
 
  826         case vdecAspectRatio32_11:
 
  829         case vdecAspectRatio80_33:
 
  832         case vdecAspectRatio18_11:
 
  835         case vdecAspectRatio15_11:
 
  838         case vdecAspectRatio64_33:
 
  841         case vdecAspectRatio160_99:
 
  844         case vdecAspectRatio4_3:
 
  847         case vdecAspectRatio16_9:
 
  850         case vdecAspectRatio221_1:
 
  855     } 
else if (ret == BC_STS_SUCCESS) {
 
  857         if (output.PoutFlags & BC_POUT_FLAGS_PIB_VALID) {
 
  868             if (priv->
last_picture + 1 < output.PicInfo.picture_number) {
 
  870                        "CrystalHD: Picture Number discontinuity\n");
 
  884             copy_ret = 
copy_frame(avctx, &output, data, got_frame);
 
  885             if (*got_frame > 0) {
 
  903     } 
else if (ret == BC_STS_BUSY) {
 
  915     BC_DTS_STATUS decoder_status = { 0, };
 
  937                        "failed to ref input packet\n");
 
  944                        "failed to send input packet\n");
 
  951                        "failed to receive output packet\n");
 
  955             in_data = filtered_packet.
data;
 
  956             len = filtered_packet.
size;
 
  973                                          in_data, len, avpkt->
pts,
 
  977                            "CrystalHD: Failed to parse h.264 packet to " 
  978                            "detect interlacing.\n");
 
  979                 } 
else if (index != len) {
 
  981                            "CrystalHD: Failed to parse h.264 packet " 
  982                            "completely. Interlaced frames may be " 
  983                            "incorrectly detected.\n");
 
  986                            "CrystalHD: parser picture type %d\n",
 
  992                        "CrystalHD: mp4toannexb filter failed to filter " 
  993                        "packet. Interlaced frames may be incorrectly " 
  998         if (len < tx_free - 1024) {
 
 1017                    "input \"pts\": %"PRIu64
"\n", pts);
 
 1018             ret = DtsProcInput(dev, in_data, len, pts, 0);
 
 1022             if (ret == BC_STS_BUSY) {
 
 1024                        "CrystalHD: ProcInput returned busy\n");
 
 1027             } 
else if (ret != BC_STS_SUCCESS) {
 
 1029                        "CrystalHD: ProcInput failed: %u\n", ret);
 
 1048     ret = DtsGetDriverStatus(dev, &decoder_status);
 
 1049     if (ret != BC_STS_SUCCESS) {
 
 1063         if (decoder_status.ReadyListCount != 0)
 
 1068     } 
else if (decoder_status.ReadyListCount == 0) {
 
 1083         if (rec_ret == 
RET_OK && *got_frame == 0) {
 
 1105                 ret = DtsGetDriverStatus(dev, &decoder_status);
 
 1106                 if (ret == BC_STS_SUCCESS &&
 
 1107                     decoder_status.ReadyListCount > 0) {
 
 1109                     if ((rec_ret == 
RET_OK && *got_frame > 0) ||
 
 1120                    "Don't output on next decode call.\n");
 
 1137 #if CONFIG_H264_CRYSTALHD_DECODER 
 1145 AVCodec ff_h264_crystalhd_decoder = {
 
 1146     .
name           = 
"h264_crystalhd",
 
 1147     .long_name      = 
NULL_IF_CONFIG_SMALL(
"H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 (CrystalHD acceleration)"),
 
 1161 #if CONFIG_MPEG2_CRYSTALHD_DECODER 
 1162 static AVClass mpeg2_class = {
 
 1169 AVCodec ff_mpeg2_crystalhd_decoder = {
 
 1170     .
name           = 
"mpeg2_crystalhd",
 
 1181     .priv_class     = &mpeg2_class,
 
 1185 #if CONFIG_MPEG4_CRYSTALHD_DECODER 
 1193 AVCodec ff_mpeg4_crystalhd_decoder = {
 
 1194     .
name           = 
"mpeg4_crystalhd",
 
 1209 #if CONFIG_MSMPEG4_CRYSTALHD_DECODER 
 1210 static AVClass msmpeg4_class = {
 
 1211     "msmpeg4_crystalhd",
 
 1217 AVCodec ff_msmpeg4_crystalhd_decoder = {
 
 1218     .
name           = 
"msmpeg4_crystalhd",
 
 1219     .long_name      = 
NULL_IF_CONFIG_SMALL(
"MPEG-4 Part 2 Microsoft variant version 3 (CrystalHD acceleration)"),
 
 1229     .priv_class     = &msmpeg4_class,
 
 1233 #if CONFIG_VC1_CRYSTALHD_DECODER 
 1241 AVCodec ff_vc1_crystalhd_decoder = {
 
 1242     .
name           = 
"vc1_crystalhd",
 
 1253     .priv_class     = &vc1_class,
 
 1257 #if CONFIG_WMV3_CRYSTALHD_DECODER 
 1265 AVCodec ff_wmv3_crystalhd_decoder = {
 
 1266     .
name           = 
"wmv3_crystalhd",
 
 1277     .priv_class     = &wmv3_class,
 
void av_bsf_free(AVBSFContext **ctx)
Free a bitstream filter context and everything associated with it; write NULL into the supplied point...
 
const struct AVCodec * codec
 
int av_image_get_linesize(enum AVPixelFormat pix_fmt, int width, int plane)
Compute the size of an image line with format pix_fmt and width width for the plane plane...
 
AVCodecParameters * par_out
Parameters of the output stream. 
 
This structure describes decoded (raw) audio or video data. 
 
ptrdiff_t const GLvoid * data
 
#define AV_LOG_WARNING
Something somehow does not look correct. 
 
#define LIBAVUTIL_VERSION_INT
 
static OpaqueList * opaque_list_pop(CHDContext *priv, uint64_t fake_timestamp)
 
The bitstream filter state. 
 
const AVBitStreamFilter * av_bsf_get_by_name(const char *name)
 
AVRational sample_aspect_ratio
sample aspect ratio (0 if unknown) That is the width of a pixel divided by the height of the pixel...
 
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx. 
 
void av_frame_set_pkt_duration(AVFrame *frame, int64_t val)
 
#define AV_CODEC_CAP_EXPERIMENTAL
Codec is experimental and is thus avoided in favor of non experimental encoders. 
 
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
 
static CopyRet receive_frame(AVCodecContext *avctx, void *data, int *got_frame)
 
void av_frame_set_pkt_size(AVFrame *frame, int val)
 
static av_cold int init(AVCodecContext *avctx)
 
int av_bsf_init(AVBSFContext *ctx)
Prepare the filter for use, after all the parameters and options have been set. 
 
#define TIMESTAMP_UNIT
Step between fake timestamps passed to hardware in units of 100ns. 
 
int av_bsf_alloc(const AVBitStreamFilter *filter, AVBSFContext **ctx)
Allocate a context for a given bitstream filter. 
 
#define AV_CODEC_CAP_DELAY
Encoder or decoder requires flushing with NULL input at the end in order to give the complete and cor...
 
int av_bsf_receive_packet(AVBSFContext *ctx, AVPacket *pkt)
Retrieve a filtered packet. 
 
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values. 
 
static av_cold int uninit(AVCodecContext *avctx)
 
int av_frame_ref(AVFrame *dst, const AVFrame *src)
Set up a new reference to the data described by the source frame. 
 
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user). 
 
uint8_t * extradata
some codecs need / can use extradata like Huffman tables. 
 
#define PICT_BOTTOM_FIELD
 
#define AV_LOG_VERBOSE
Detailed information. 
 
int interlaced_frame
The content of the picture is interlaced. 
 
int av_packet_ref(AVPacket *dst, const AVPacket *src)
Setup a new reference to the data described by a given packet. 
 
AVCodecID
Identify the syntax and semantics of the bitstream. 
 
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered. 
 
int has_b_frames
Size of the frame reordering buffer in the decoder. 
 
static const AVClass h264_class
 
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g. 
 
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
 
static void flush(AVCodecContext *avctx)
 
const char * name
Name of the codec implementation. 
 
static uint64_t opaque_list_push(CHDContext *priv, uint64_t reordered_opaque, uint8_t pic_type)
 
#define WAIT_UNIT
Increment in us to adjust wait in decode() 
 
AVCodecParserContext * parser
 
int extradata_size
Size of the extradata content in bytes. 
 
static void print_frame_info(CHDContext *priv, BC_DTS_PROC_OUT *output)
 
int av_parser_parse2(AVCodecParserContext *s, AVCodecContext *avctx, uint8_t **poutbuf, int *poutbuf_size, const uint8_t *buf, int buf_size, int64_t pts, int64_t dts, int64_t pos)
Parse a packet. 
 
static const AVOption options[]
 
int width
picture width / height. 
 
static int filter_packet(AVFormatContext *avf, ConcatStream *cs, AVPacket *pkt)
 
int av_bsf_send_packet(AVBSFContext *ctx, AVPacket *pkt)
Submit a packet for filtering. 
 
void av_parser_close(AVCodecParserContext *s)
 
void av_frame_set_pkt_pos(AVFrame *frame, int64_t val)
 
uint64_t reordered_opaque
 
H.264 / AVC / MPEG-4 part10 codec. 
 
#define AVERROR_BSF_NOT_FOUND
Bitstream filter not found. 
 
preferred ID for MPEG-1/2 video decoding 
 
#define AV_LOG_INFO
Standard information. 
 
AVCodecParserContext * av_parser_init(int codec_id)
 
static av_cold int init_bsf(AVCodecContext *avctx, const char *bsf_name)
 
Libavcodec external API header. 
 
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line. 
 
uint32_t orig_extradata_size
 
#define AV_OPT_FLAG_VIDEO_PARAM
 
main external API structure. 
 
void av_packet_unref(AVPacket *pkt)
Wipe the packet. 
 
int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
Get a buffer for a frame. 
 
packed YUV 4:2:2, 16bpp, Y0 Cb Y1 Cr 
 
static const char * format
 
Describe the class of an AVClass context structure. 
 
static BC_MEDIA_SUBTYPE id2subtype(CHDContext *priv, enum AVCodecID id)
 
uint8_t need_second_field
 
Rational number (pair of numerator and denominator). 
 
int avcodec_parameters_from_context(AVCodecParameters *par, const AVCodecContext *codec)
Fill the parameters struct based on the values from the supplied codec context. 
 
#define AV_OPT_FLAG_DECODING_PARAM
a generic parameter which can be set by the user for demuxing or decoding 
 
static enum AVPixelFormat pix_fmts[]
 
void av_frame_unref(AVFrame *frame)
Unreference all the buffers referenced by frame and reset the frame fields. 
 
static int64_t pts
Global timestamp for the audio frames. 
 
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes. 
 
attribute_deprecated int64_t pkt_pts
PTS copied from the AVPacket that was decoded to produce this frame. 
 
#define FF_DISABLE_DEPRECATION_WARNINGS
 
common internal api header. 
 
#define OUTPUT_PROC_TIMEOUT
Timeout parameter passed to DtsProcOutput() in us. 
 
#define PARSER_FLAG_COMPLETE_FRAMES
 
#define AV_INPUT_BUFFER_PADDING_SIZE
Required number of additionally allocated bytes at the end of the input bitstream for decoding...
 
static const AVClass mpeg4_class
 
#define FF_ENABLE_DEPRECATION_WARNINGS
 
#define BASE_WAIT
Initial value in us of the wait in decode() 
 
int top_field_first
If the content is interlaced, is top field displayed first. 
 
uint8_t * extradata
Extra binary data needed for initializing the decoder, codec-dependent. 
 
int64_t dts
Decompression timestamp in AVStream->time_base units; the time at which the packet is decompressed...
 
static int decode(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
 
void av_image_copy_plane(uint8_t *dst, int dst_linesize, const uint8_t *src, int src_linesize, int bytewidth, int height)
Copy image plane from src to dst. 
 
AVPixelFormat
Pixel format. 
 
This structure stores compressed data. 
 
AVCodecParameters * par_in
Parameters of the input stream. 
 
#define AV_GET_BUFFER_FLAG_REF
The decoder will keep a reference to the frame and may reuse it later. 
 
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() for allocating buffers and supports custom allocators. 
 
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
 
#define AV_NOPTS_VALUE
Undefined timestamp value. 
 
static CopyRet copy_frame(AVCodecContext *avctx, BC_DTS_PROC_OUT *output, void *data, int *got_frame)