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 
  157     { 
"crystalhd_downscale_width",
 
  158       "Turn on downscaling to the specified width",
 
  174         return BC_MSUBTYPE_DIVX;
 
  176         return BC_MSUBTYPE_DIVX311;
 
  178         return BC_MSUBTYPE_MPEG2VIDEO;
 
  180         return BC_MSUBTYPE_VC1;
 
  182         return BC_MSUBTYPE_WMV3;
 
  184         return priv->
is_nal ? BC_MSUBTYPE_AVC1 : BC_MSUBTYPE_H264;
 
  186         return BC_MSUBTYPE_INVALID;
 
  194            output->YBuffDoneSz);
 
  196            output->UVBuffDoneSz);
 
  198            output->PicInfo.timeStamp);
 
  200            output->PicInfo.picture_number);
 
  202            output->PicInfo.width);
 
  204            output->PicInfo.height);
 
  206            output->PicInfo.chroma_format);
 
  208            output->PicInfo.pulldown);
 
  210            output->PicInfo.flags);
 
  212            output->PicInfo.frame_rate);
 
  214            output->PicInfo.aspect_ratio);
 
  216            output->PicInfo.colour_primaries);
 
  218            output->PicInfo.picture_meta_payload);
 
  220            output->PicInfo.sess_num);
 
  222            output->PicInfo.ycom);
 
  224            output->PicInfo.custom_aspect_ratio_width_height);
 
  226            output->PicInfo.n_drop);
 
  228            output->PicInfo.other.h264.valid);
 
  242                "Unable to allocate new node in OpaqueList.\n");
 
  247         priv->
head              = newNode;
 
  252     priv->
tail = newNode;
 
  272                "CrystalHD: Attempted to query non-existent timestamps.\n");
 
  310            "CrystalHD: Couldn't match fake_timestamp.\n");
 
  333     DtsFlushInput(priv->
dev, 4);
 
  343     DtsStopDecoder(device);
 
  344     DtsCloseDecoder(device);
 
  345     DtsDeviceClose(device);
 
  387     BC_INPUT_FORMAT format = {
 
  390         .OptFlags    = 0x80000000 | vdecFrameRate59_94 | 0x40,
 
  391         .width       = avctx->
width,
 
  395     BC_MEDIA_SUBTYPE subtype;
 
  397     uint32_t 
mode = DTS_PLAYBACK_MODE |
 
  398                     DTS_LOAD_FILE_PLAY_FW |
 
  399                     DTS_SKIP_TX_CHK_CPB |
 
  400                     DTS_PLAYBACK_DROP_RPT_MODE |
 
  401                     DTS_SINGLE_THREADED_MODE |
 
  402                     DTS_DFLT_RESOLUTION(vdecRESOLUTION_1080p23_976);
 
  419     case BC_MSUBTYPE_AVC1:
 
  428                        "Failed to allocate copy of extradata\n");
 
  437                        "Cannot open the h264_mp4toannexb BSF!\n");
 
  441                                        &dummy_int, 
NULL, 0, 0);
 
  443         subtype = BC_MSUBTYPE_H264;
 
  445     case BC_MSUBTYPE_H264:
 
  446         format.startCodeSz = 4;
 
  448     case BC_MSUBTYPE_VC1:
 
  449     case BC_MSUBTYPE_WVC1:
 
  450     case BC_MSUBTYPE_WMV3:
 
  451     case BC_MSUBTYPE_WMVA:
 
  452     case BC_MSUBTYPE_MPEG2VIDEO:
 
  453     case BC_MSUBTYPE_DIVX:
 
  454     case BC_MSUBTYPE_DIVX311:
 
  462     format.mSubtype = subtype;
 
  465         format.bEnableScaling = 1;
 
  466         format.ScalingParams.sWidth = priv->
sWidth;
 
  472     ret = DtsDeviceOpen(&priv->
dev, mode);
 
  473     if (ret != BC_STS_SUCCESS) {
 
  478     ret = DtsCrystalHDVersion(priv->
dev, &version);
 
  479     if (ret != BC_STS_SUCCESS) {
 
  481                "CrystalHD: DtsCrystalHDVersion failed\n");
 
  484     priv->
is_70012 = version.device == 0;
 
  487         (subtype == BC_MSUBTYPE_DIVX || subtype == BC_MSUBTYPE_DIVX311)) {
 
  489                "CrystalHD: BCM70012 doesn't support MPEG4-ASP/DivX/Xvid\n");
 
  493     ret = DtsSetInputFormat(priv->
dev, &format);
 
  494     if (ret != BC_STS_SUCCESS) {
 
  499     ret = DtsOpenDecoder(priv->
dev, BC_STREAM_TYPE_ES);
 
  500     if (ret != BC_STS_SUCCESS) {
 
  505     ret = DtsSetColorSpace(priv->
dev, OUTPUT_MODE422_YUY2);
 
  506     if (ret != BC_STS_SUCCESS) {
 
  510     ret = DtsStartDecoder(priv->
dev);
 
  511     if (ret != BC_STS_SUCCESS) {
 
  515     ret = DtsStartCapture(priv->
dev);
 
  516     if (ret != BC_STS_SUCCESS) {
 
  525                    "Cannot open the h.264 parser! Interlaced h.264 content " 
  526                    "will not be detected reliably.\n");
 
  540                                  BC_DTS_PROC_OUT *output,
 
  541                                  void *
data, 
int *got_frame)
 
  544     BC_DTS_STATUS decoder_status = { 0, };
 
  552     uint8_t bottom_field = (output->PicInfo.flags & VDEC_FLAG_BOTTOMFIELD) ==
 
  553                            VDEC_FLAG_BOTTOMFIELD;
 
  554     uint8_t bottom_first = !!(output->PicInfo.flags & VDEC_FLAG_BOTTOM_FIRST);
 
  556     int width    = output->PicInfo.width;
 
  557     int height   = output->PicInfo.height;
 
  564     if (output->PicInfo.timeStamp != 0) {
 
  582                output->PicInfo.timeStamp);
 
  587     ret = DtsGetDriverStatus(priv->
dev, &decoder_status);
 
  588     if (ret != BC_STS_SUCCESS) {
 
  590                "CrystalHD: GetDriverStatus failed: %u\n", ret);
 
  611                        !(output->PicInfo.flags & VDEC_FLAG_UNKNOWN_SRC) ||
 
  613                        (decoder_status.picNumFlags & ~0x40000000) ==
 
  614                        output->PicInfo.picture_number;
 
  624                "Incorrectly guessed progressive frame. Discarding second field\n");
 
  629     interlaced = (output->PicInfo.flags & VDEC_FLAG_INTERLACED_SRC) &&
 
  632     if (!trust_interlaced && (decoder_status.picNumFlags & ~0x40000000) == 0) {
 
  634                "Next picture number unknown. Assuming progressive frame.\n");
 
  638            interlaced, trust_interlaced);
 
  656         else if (width <= 1280)
 
  682         for (sY = 0; sY < 
height; dY++, sY++) {
 
  683             memcpy(&(dst[dY * dStride]), &(src[sY * sStride]), bwidth);
 
  710     if (!interlaced && (output->PicInfo.flags & VDEC_FLAG_UNKNOWN_SRC) &&
 
  729            (!(output->PicInfo.flags & VDEC_FLAG_UNKNOWN_SRC) ||
 
  736                                     void *
data, 
int *got_frame)
 
  739     BC_DTS_PROC_OUT output = {
 
  740         .PicInfo.width  = avctx->
width,
 
  741         .PicInfo.height = avctx->
height,
 
  750     if (ret == BC_STS_FMT_CHANGE) {
 
  752         avctx->
width  = output.PicInfo.width;
 
  753         avctx->
height = output.PicInfo.height;
 
  754         switch ( output.PicInfo.aspect_ratio ) {
 
  755         case vdecAspectRatioSquare:
 
  758         case vdecAspectRatio12_11:
 
  761         case vdecAspectRatio10_11:
 
  764         case vdecAspectRatio16_11:
 
  767         case vdecAspectRatio40_33:
 
  770         case vdecAspectRatio24_11:
 
  773         case vdecAspectRatio20_11:
 
  776         case vdecAspectRatio32_11:
 
  779         case vdecAspectRatio80_33:
 
  782         case vdecAspectRatio18_11:
 
  785         case vdecAspectRatio15_11:
 
  788         case vdecAspectRatio64_33:
 
  791         case vdecAspectRatio160_99:
 
  794         case vdecAspectRatio4_3:
 
  797         case vdecAspectRatio16_9:
 
  800         case vdecAspectRatio221_1:
 
  805     } 
else if (ret == BC_STS_SUCCESS) {
 
  807         if (output.PoutFlags & BC_POUT_FLAGS_PIB_VALID) {
 
  817                 output.PicInfo.timeStamp == 0 && priv->
bframe_bug) {
 
  819                        "CrystalHD: Not returning packed frame twice.\n");
 
  827             if (priv->
last_picture + 1 < output.PicInfo.picture_number) {
 
  829                        "CrystalHD: Picture Number discontinuity\n");
 
  843             copy_ret = 
copy_frame(avctx, &output, data, got_frame);
 
  844             if (*got_frame > 0) {
 
  862     } 
else if (ret == BC_STS_BUSY) {
 
  874     BC_DTS_STATUS decoder_status = { 0, };
 
  890                "CrystalHD: Enabling work-around for packed b-frame bug\n");
 
  897                "CrystalHD: Disabling work-around for packed b-frame bug\n");
 
  910                                                  avpkt->
data, len, 0);
 
  925                            "CrystalHD: Failed to parse h.264 packet to " 
  926                            "detect interlacing.\n");
 
  927                 } 
else if (index != len) {
 
  929                            "CrystalHD: Failed to parse h.264 packet " 
  930                            "completely. Interlaced frames may be " 
  931                            "incorrectly detected.\n");
 
  934                            "CrystalHD: parser picture type %d\n",
 
  940                        "CrystalHD: mp4toannexb filter failed to filter " 
  941                        "packet. Interlaced frames may be incorrectly " 
  946         if (len < tx_free - 1024) {
 
  964                    "input \"pts\": %"PRIu64
"\n", pts);
 
  965             ret = DtsProcInput(dev, in_data, len, pts, 0);
 
  969             if (ret == BC_STS_BUSY) {
 
  971                        "CrystalHD: ProcInput returned busy\n");
 
  974             } 
else if (ret != BC_STS_SUCCESS) {
 
  976                        "CrystalHD: ProcInput failed: %u\n", ret);
 
  995     ret = DtsGetDriverStatus(dev, &decoder_status);
 
  996     if (ret != BC_STS_SUCCESS) {
 
 1010         if (decoder_status.ReadyListCount != 0)
 
 1015     } 
else if (decoder_status.ReadyListCount == 0) {
 
 1030         if (rec_ret == 
RET_OK && *got_frame == 0) {
 
 1052                 ret = DtsGetDriverStatus(dev, &decoder_status);
 
 1053                 if (ret == BC_STS_SUCCESS &&
 
 1054                     decoder_status.ReadyListCount > 0) {
 
 1056                     if ((rec_ret == 
RET_OK && *got_frame > 0) ||
 
 1067                    "Don't output on next decode call.\n");
 
 1084 #if CONFIG_H264_CRYSTALHD_DECODER 
 1092 AVCodec ff_h264_crystalhd_decoder = {
 
 1093     .
name           = 
"h264_crystalhd",
 
 1094     .long_name      = 
NULL_IF_CONFIG_SMALL(
"H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 (CrystalHD acceleration)"),
 
 1108 #if CONFIG_MPEG2_CRYSTALHD_DECODER 
 1109 static AVClass mpeg2_class = {
 
 1116 AVCodec ff_mpeg2_crystalhd_decoder = {
 
 1117     .
name           = 
"mpeg2_crystalhd",
 
 1128     .priv_class     = &mpeg2_class,
 
 1132 #if CONFIG_MPEG4_CRYSTALHD_DECODER 
 1140 AVCodec ff_mpeg4_crystalhd_decoder = {
 
 1141     .
name           = 
"mpeg4_crystalhd",
 
 1156 #if CONFIG_MSMPEG4_CRYSTALHD_DECODER 
 1157 static AVClass msmpeg4_class = {
 
 1158     "msmpeg4_crystalhd",
 
 1164 AVCodec ff_msmpeg4_crystalhd_decoder = {
 
 1165     .
name           = 
"msmpeg4_crystalhd",
 
 1166     .long_name      = 
NULL_IF_CONFIG_SMALL(
"MPEG-4 Part 2 Microsoft variant version 3 (CrystalHD acceleration)"),
 
 1176     .priv_class     = &msmpeg4_class,
 
 1180 #if CONFIG_VC1_CRYSTALHD_DECODER 
 1188 AVCodec ff_vc1_crystalhd_decoder = {
 
 1189     .
name           = 
"vc1_crystalhd",
 
 1200     .priv_class     = &vc1_class,
 
 1204 #if CONFIG_WMV3_CRYSTALHD_DECODER 
 1212 AVCodec ff_wmv3_crystalhd_decoder = {
 
 1213     .
name           = 
"wmv3_crystalhd",
 
 1224     .priv_class     = &wmv3_class,
 
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...
This structure describes decoded (raw) audio or video data. 
static const AVClass h264_class
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)
AVRational sample_aspect_ratio
sample aspect ratio (0 if unknown) That is the width of a pixel divided by the height of the pixel...
AVPacket * pkt
Current packet as passed into the decoder, to avoid having to pass the packet into every function...
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx. 
static CopyRet receive_frame(AVCodecContext *avctx, void *data, int *got_frame)
static av_cold int init(AVCodecContext *avctx)
#define TIMESTAMP_UNIT
Step between fake timestamps passed to hardware in units of 100ns. 
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. 
uint8_t * extradata
some codecs need / can use extradata like Huffman tables. 
#define CODEC_CAP_DR1
Codec uses get_buffer() for allocating buffers and supports custom allocators. 
#define PICT_BOTTOM_FIELD
#define AV_LOG_VERBOSE
Detailed information. 
int interlaced_frame
The content of the picture is interlaced. 
H.264 / AVC / MPEG4 part10 codec. 
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. 
#define CODEC_CAP_DELAY
Encoder or decoder requires flushing with NULL input at the end in order to give the complete and cor...
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g. 
#define PARSER_FLAG_COMPLETE_FRAMES
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
void av_bitstream_filter_close(AVBitStreamFilterContext *bsf)
Release bitstream filter context. 
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)
AVBitStreamFilterContext * bsfc
#define WAIT_UNIT
Increment in us to adjust wait in decode() 
Libavcodec external API header. 
AVCodecParserContext * parser
static void print_frame_info(CHDContext *priv, BC_DTS_PROC_OUT *output)
#define FF_INPUT_BUFFER_PADDING_SIZE
Required number of additionally allocated bytes at the end of the input bitstream for decoding...
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. 
AVBitStreamFilterContext * av_bitstream_filter_init(const char *name)
Create and initialize a bitstream filter context given a bitstream filter name. 
void av_parser_close(AVCodecParserContext *s)
uint64_t reordered_opaque
#define AVERROR_BSF_NOT_FOUND
Bitstream filter not found. 
preferred ID for MPEG-1/2 video decoding 
#define AV_LOG_INFO
Standard information. 
int av_bitstream_filter_filter(AVBitStreamFilterContext *bsfc, AVCodecContext *avctx, const char *args, uint8_t **poutbuf, int *poutbuf_size, const uint8_t *buf, int buf_size, int keyframe)
Filter bitstream. 
AVCodecParserContext * av_parser_init(int codec_id)
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. 
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 
BYTE int const BYTE int int int height
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 numerator/denominator 
#define AV_OPT_FLAG_DECODING_PARAM
a generic parameter which can be set by the user for demuxing or decoding 
int64_t pkt_pts
PTS copied from the AVPacket that was decoded to produce this frame. 
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. 
common internal api header. 
#define OUTPUT_PROC_TIMEOUT
Timeout parameter passed to DtsProcOutput() in us. 
#define CODEC_CAP_EXPERIMENTAL
Codec is experimental and is thus avoided in favor of non experimental encoders. 
static const AVClass mpeg4_class
#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. 
struct AVCodecInternal * internal
Private context used for internal data. 
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. 
#define AV_GET_BUFFER_FLAG_REF
The decoder will keep a reference to the frame and may reuse it later. 
void * av_mallocz(size_t size)
Allocate a block of size bytes with alignment suitable for all memory accesses (including vectors if ...
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)