48 #define _XOPEN_SOURCE 600 
   53 #include <libcrystalhd/bc_dts_types.h> 
   54 #include <libcrystalhd/bc_dts_defs.h> 
   55 #include <libcrystalhd/libcrystalhd_if.h> 
   69 #define OUTPUT_PROC_TIMEOUT 50 
   71 #define TIMESTAMP_UNIT 100000 
  107     { 
"crystalhd_downscale_width",
 
  108       "Turn on downscaling to the specified width",
 
  124         return BC_MSUBTYPE_DIVX;
 
  126         return BC_MSUBTYPE_DIVX311;
 
  128         return BC_MSUBTYPE_MPEG2VIDEO;
 
  130         return BC_MSUBTYPE_VC1;
 
  132         return BC_MSUBTYPE_WMV3;
 
  134         return BC_MSUBTYPE_H264;
 
  136         return BC_MSUBTYPE_INVALID;
 
  144            output->YBuffDoneSz);
 
  146            output->UVBuffDoneSz);
 
  148            output->PicInfo.timeStamp);
 
  150            output->PicInfo.picture_number);
 
  152            output->PicInfo.width);
 
  154            output->PicInfo.height);
 
  156            output->PicInfo.chroma_format);
 
  158            output->PicInfo.pulldown);
 
  160            output->PicInfo.flags);
 
  162            output->PicInfo.frame_rate);
 
  164            output->PicInfo.aspect_ratio);
 
  166            output->PicInfo.colour_primaries);
 
  168            output->PicInfo.picture_meta_payload);
 
  170            output->PicInfo.sess_num);
 
  172            output->PicInfo.ycom);
 
  174            output->PicInfo.custom_aspect_ratio_width_height);
 
  176            output->PicInfo.n_drop);
 
  178            output->PicInfo.other.h264.valid);
 
  191                "Unable to allocate new node in OpaqueList.\n");
 
  196         priv->
head              = newNode;
 
  201     priv->
tail = newNode;
 
  220                "CrystalHD: Attempted to query non-existent timestamps.\n");
 
  258            "CrystalHD: Couldn't match fake_timestamp.\n");
 
  275     DtsFlushInput(priv->
dev, 4);
 
  285     DtsStopDecoder(device);
 
  286     DtsCloseDecoder(device);
 
  287     DtsDeviceClose(device);
 
  306     BC_INPUT_FORMAT 
format = {
 
  309         .OptFlags    = 0x80000000 | vdecFrameRate59_94 | 0x40,
 
  310         .width       = avctx->
width,
 
  314     BC_MEDIA_SUBTYPE subtype;
 
  316     uint32_t 
mode = DTS_PLAYBACK_MODE |
 
  317                     DTS_LOAD_FILE_PLAY_FW |
 
  318                     DTS_SKIP_TX_CHK_CPB |
 
  319                     DTS_PLAYBACK_DROP_RPT_MODE |
 
  320                     DTS_SINGLE_THREADED_MODE |
 
  321                     DTS_DFLT_RESOLUTION(vdecRESOLUTION_1080p23_976);
 
  335     case BC_MSUBTYPE_H264:
 
  336         format.startCodeSz = 4;
 
  338     case BC_MSUBTYPE_VC1:
 
  339     case BC_MSUBTYPE_WVC1:
 
  340     case BC_MSUBTYPE_WMV3:
 
  341     case BC_MSUBTYPE_WMVA:
 
  342     case BC_MSUBTYPE_MPEG2VIDEO:
 
  343     case BC_MSUBTYPE_DIVX:
 
  344     case BC_MSUBTYPE_DIVX311:
 
  352     format.mSubtype = subtype;
 
  355         format.bEnableScaling = 1;
 
  356         format.ScalingParams.sWidth = priv->
sWidth;
 
  362     ret = DtsDeviceOpen(&priv->
dev, mode);
 
  363     if (ret != BC_STS_SUCCESS) {
 
  368     ret = DtsCrystalHDVersion(priv->
dev, &version);
 
  369     if (ret != BC_STS_SUCCESS) {
 
  371                "CrystalHD: DtsCrystalHDVersion failed\n");
 
  374     priv->
is_70012 = version.device == 0;
 
  377         (subtype == BC_MSUBTYPE_DIVX || subtype == BC_MSUBTYPE_DIVX311)) {
 
  379                "CrystalHD: BCM70012 doesn't support MPEG4-ASP/DivX/Xvid\n");
 
  383     ret = DtsSetInputFormat(priv->
dev, &format);
 
  384     if (ret != BC_STS_SUCCESS) {
 
  389     ret = DtsOpenDecoder(priv->
dev, BC_STREAM_TYPE_ES);
 
  390     if (ret != BC_STS_SUCCESS) {
 
  395     ret = DtsSetColorSpace(priv->
dev, OUTPUT_MODE422_YUY2);
 
  396     if (ret != BC_STS_SUCCESS) {
 
  400     ret = DtsStartDecoder(priv->
dev);
 
  401     if (ret != BC_STS_SUCCESS) {
 
  405     ret = DtsStartCapture(priv->
dev);
 
  406     if (ret != BC_STS_SUCCESS) {
 
  422                                  BC_DTS_PROC_OUT *output,
 
  426     BC_DTS_STATUS decoder_status = { 0, };
 
  432     uint8_t bottom_field = (output->PicInfo.flags & VDEC_FLAG_BOTTOMFIELD) ==
 
  433                            VDEC_FLAG_BOTTOMFIELD;
 
  434     uint8_t bottom_first = !!(output->PicInfo.flags & VDEC_FLAG_BOTTOM_FIRST);
 
  436     int width    = output->PicInfo.width;
 
  437     int height   = output->PicInfo.height;
 
  444     if (output->PicInfo.timeStamp != 0) {
 
  459                output->PicInfo.timeStamp);
 
  462     ret = DtsGetDriverStatus(priv->
dev, &decoder_status);
 
  463     if (ret != BC_STS_SUCCESS) {
 
  465                "CrystalHD: GetDriverStatus failed: %u\n", ret);
 
  469     interlaced = output->PicInfo.flags & VDEC_FLAG_INTERLACED_SRC;
 
  476     if (!frame->
data[0]) {
 
  490         else if (width <= 1280)
 
  501     dst     = frame->
data[0];
 
  512     *((uint32_t *)src) = *((uint32_t *)(src + sStride));
 
  527         for (sY = 0; sY < 
height; dY++, sY++) {
 
  528             memcpy(&(dst[dY * dStride]), &(src[sY * sStride]), bwidth);
 
  539     frame->
pts = pkt_pts;
 
  564     BC_DTS_PROC_OUT output = {
 
  565         .PicInfo.width  = avctx->
width,
 
  566         .PicInfo.height = avctx->
height,
 
  575     if (ret == BC_STS_FMT_CHANGE) {
 
  577         avctx->
width  = output.PicInfo.width;
 
  578         avctx->
height = output.PicInfo.height;
 
  579         switch ( output.PicInfo.aspect_ratio ) {
 
  580         case vdecAspectRatioSquare:
 
  583         case vdecAspectRatio12_11:
 
  586         case vdecAspectRatio10_11:
 
  589         case vdecAspectRatio16_11:
 
  592         case vdecAspectRatio40_33:
 
  595         case vdecAspectRatio24_11:
 
  598         case vdecAspectRatio20_11:
 
  601         case vdecAspectRatio32_11:
 
  604         case vdecAspectRatio80_33:
 
  607         case vdecAspectRatio18_11:
 
  610         case vdecAspectRatio15_11:
 
  613         case vdecAspectRatio64_33:
 
  616         case vdecAspectRatio160_99:
 
  619         case vdecAspectRatio4_3:
 
  622         case vdecAspectRatio16_9:
 
  625         case vdecAspectRatio221_1:
 
  630     } 
else if (ret == BC_STS_SUCCESS) {
 
  632         if (output.PoutFlags & BC_POUT_FLAGS_PIB_VALID) {
 
  635             copy_ret = 
copy_frame(avctx, &output, frame, got_frame);
 
  647     } 
else if (ret == BC_STS_BUSY) {
 
  665     if (avpkt && avpkt->
size) {
 
  683                "input \"pts\": %"PRIu64
"\n", pts);
 
  684         bc_ret = DtsProcInput(dev, avpkt->
data, avpkt->
size, pts, 0);
 
  685         if (bc_ret == BC_STS_BUSY) {
 
  687                    "CrystalHD: ProcInput returned busy\n");
 
  690         } 
else if (bc_ret != BC_STS_SUCCESS) {
 
  692                    "CrystalHD: ProcInput failed: %u\n", ret);
 
  710     BC_DTS_STATUS decoder_status = { 0, };
 
  725     while (pkt.
size > DtsTxFreeSize(dev)) {
 
  745         bc_ret = DtsGetDriverStatus(dev, &decoder_status);
 
  746         if (bc_ret != BC_STS_SUCCESS) {
 
  751         if (decoder_status.ReadyListCount == 0) {
 
  763     } 
else if (got_frame == 0) {
 
  770 #define DEFINE_CRYSTALHD_DECODER(x, X, bsf_name) \ 
  771     static const AVClass x##_crystalhd_class = { \ 
  772         .class_name = #x "_crystalhd", \ 
  773         .item_name = av_default_item_name, \ 
  775         .version = LIBAVUTIL_VERSION_INT, \ 
  777     AVCodec ff_##x##_crystalhd_decoder = { \ 
  778         .name           = #x "_crystalhd", \ 
  779         .long_name      = NULL_IF_CONFIG_SMALL("CrystalHD " #X " decoder"), \ 
  780         .type           = AVMEDIA_TYPE_VIDEO, \ 
  781         .id             = AV_CODEC_ID_##X, \ 
  782         .priv_data_size = sizeof(CHDContext), \ 
  783         .priv_class     = &x##_crystalhd_class, \ 
  786         .receive_frame  = crystalhd_receive_frame, \ 
  789         .capabilities   = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AVOID_PROBING | AV_CODEC_CAP_HARDWARE, \ 
  790         .pix_fmts       = (const enum AVPixelFormat[]){AV_PIX_FMT_YUYV422, AV_PIX_FMT_NONE}, \ 
  791         .wrapper_name   = "crystalhd", \ 
  794 #if CONFIG_H264_CRYSTALHD_DECODER 
  798 #if CONFIG_MPEG2_CRYSTALHD_DECODER 
  802 #if CONFIG_MPEG4_CRYSTALHD_DECODER 
  806 #if CONFIG_MSMPEG4_CRYSTALHD_DECODER 
  810 #if CONFIG_VC1_CRYSTALHD_DECODER 
  814 #if CONFIG_WMV3_CRYSTALHD_DECODER 
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...
static const char * format[]
This structure describes decoded (raw) audio or video data. 
int64_t pkt_pos
reordered pos from the last AVPacket that has been input into the decoder 
#define AV_LOG_WARNING
Something somehow does not look correct. 
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...
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx. 
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, AVFrame *frame, int *got_frame)
#define DEFINE_CRYSTALHD_DECODER(x, X, bsf_name)
static av_cold int init(AVCodecContext *avctx)
#define TIMESTAMP_UNIT
Step between fake timestamps passed to hardware in units of 100ns. 
static av_cold int uninit(AVCodecContext *avctx)
#define AV_LOG_TRACE
Extremely verbose debugging, useful for libav* development. 
int ff_decode_get_packet(AVCodecContext *avctx, AVPacket *pkt)
Called by decoders to get the next packet for decoding. 
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. 
static int crystalhd_decode_packet(AVCodecContext *avctx, const AVPacket *avpkt)
#define AVERROR_EOF
End of file. 
#define AV_LOG_VERBOSE
Detailed information. 
int interlaced_frame
The content of the picture is interlaced. 
AVCodecID
Identify the syntax and semantics of the bitstream. 
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered. 
static int crystalhd_receive_frame(AVCodecContext *avctx, AVFrame *frame)
static void flush(AVCodecContext *avctx)
const char * name
Name of the codec implementation. 
static void print_frame_info(CHDContext *priv, BC_DTS_PROC_OUT *output)
static const AVOption options[]
int width
picture width / height. 
uint64_t reordered_opaque
preferred ID for MPEG-1/2 video decoding 
#define AV_LOG_INFO
Standard information. 
Libavcodec external API header. 
int64_t pkt_duration
duration of the corresponding packet, expressed in AVStream->time_base units, 0 if unknown...
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line. 
#define AV_OPT_FLAG_VIDEO_PARAM
main external API structure. 
void av_packet_unref(AVPacket *pkt)
Wipe the packet. 
packed YUV 4:2:2, 16bpp, Y0 Cb Y1 Cr 
int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
Get a buffer for a frame. 
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). 
#define AV_OPT_FLAG_DECODING_PARAM
a generic parameter which can be set by the user for demuxing or decoding 
static CopyRet copy_frame(AVCodecContext *avctx, BC_DTS_PROC_OUT *output, AVFrame *frame, int *got_frame)
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. 
static uint64_t opaque_list_push(CHDContext *priv, uint64_t reordered_opaque)
#define OUTPUT_PROC_TIMEOUT
Timeout parameter passed to DtsProcOutput() in us. 
#define FF_ENABLE_DEPRECATION_WARNINGS
int top_field_first
If the content is interlaced, is top field displayed first. 
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. 
int pkt_size
size of the corresponding packet containing the compressed frame. 
#define AVERROR_EXTERNAL
Generic error in an external library. 
This structure stores compressed data. 
mode
Use these values in ebur128_init (or'ed). 
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.