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:
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;
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");
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;
490 else if (
width <= 1280)
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);
564 BC_DTS_PROC_OUT output = {
565 .PicInfo.width = avctx->
width,
566 .PicInfo.height = avctx->
height,
569 HANDLE dev = priv->
dev;
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) {
644 DtsReleaseOutputBuffs(dev,
NULL, FALSE);
647 }
else if (ret == BC_STS_BUSY) {
659 HANDLE dev = priv->
dev;
664 if (avpkt && avpkt->
size) {
682 "input \"pts\": %"PRIu64
"\n",
pts);
683 bc_ret = DtsProcInput(dev, avpkt->
data, avpkt->
size,
pts, 0);
684 if (bc_ret == BC_STS_BUSY) {
686 "CrystalHD: ProcInput returned busy\n");
689 }
else if (bc_ret != BC_STS_SUCCESS) {
691 "CrystalHD: ProcInput failed: %u\n", ret);
708 BC_DTS_STATUS decoder_status = { 0, };
711 HANDLE dev = priv->
dev;
723 while (
pkt.
size > DtsTxFreeSize(dev)) {
743 bc_ret = DtsGetDriverStatus(dev, &decoder_status);
744 if (bc_ret != BC_STS_SUCCESS) {
749 if (decoder_status.ReadyListCount == 0) {
761 }
else if (got_frame == 0) {
768 #define DEFINE_CRYSTALHD_DECODER(x, X, bsf_name) \
769 static const AVClass x##_crystalhd_class = { \
770 .class_name = #x "_crystalhd", \
771 .item_name = av_default_item_name, \
773 .version = LIBAVUTIL_VERSION_INT, \
775 AVCodec ff_##x##_crystalhd_decoder = { \
776 .name = #x "_crystalhd", \
777 .long_name = NULL_IF_CONFIG_SMALL("CrystalHD " #X " decoder"), \
778 .type = AVMEDIA_TYPE_VIDEO, \
779 .id = AV_CODEC_ID_##X, \
780 .priv_data_size = sizeof(CHDContext), \
781 .priv_class = &x##_crystalhd_class, \
784 .receive_frame = crystalhd_receive_frame, \
787 .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AVOID_PROBING | AV_CODEC_CAP_HARDWARE, \
788 .pix_fmts = (const enum AVPixelFormat[]){AV_PIX_FMT_YUYV422, AV_PIX_FMT_NONE}, \
789 .wrapper_name = "crystalhd", \
792 #if CONFIG_H264_CRYSTALHD_DECODER
796 #if CONFIG_MPEG2_CRYSTALHD_DECODER
800 #if CONFIG_MPEG4_CRYSTALHD_DECODER
804 #if CONFIG_MSMPEG4_CRYSTALHD_DECODER
808 #if CONFIG_VC1_CRYSTALHD_DECODER
812 #if CONFIG_WMV3_CRYSTALHD_DECODER
static const char *const format[]
Libavcodec external API header.
static void print_frame_info(CHDContext *priv, BC_DTS_PROC_OUT *output)
static const AVOption options[]
static av_cold int init(AVCodecContext *avctx)
static int crystalhd_decode_packet(AVCodecContext *avctx, const AVPacket *avpkt)
static CopyRet copy_frame(AVCodecContext *avctx, BC_DTS_PROC_OUT *output, AVFrame *frame, int *got_frame)
static av_cold int uninit(AVCodecContext *avctx)
#define DEFINE_CRYSTALHD_DECODER(x, X, bsf_name)
static BC_MEDIA_SUBTYPE id2subtype(CHDContext *priv, enum AVCodecID id)
static uint64_t opaque_list_push(CHDContext *priv, uint64_t reordered_opaque)
static int crystalhd_receive_frame(AVCodecContext *avctx, AVFrame *frame)
static CopyRet receive_frame(AVCodecContext *avctx, AVFrame *frame, int *got_frame)
#define TIMESTAMP_UNIT
Step between fake timestamps passed to hardware in units of 100ns.
#define OUTPUT_PROC_TIMEOUT
Timeout parameter passed to DtsProcOutput() in us.
static OpaqueList * opaque_list_pop(CHDContext *priv, uint64_t fake_timestamp)
static void flush(AVCodecContext *avctx)
int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
Get a buffer for a frame.
int ff_decode_get_packet(AVCodecContext *avctx, AVPacket *pkt)
Called by decoders to get the next packet for decoding.
mode
Use these values in ebur128_init (or'ed).
AVCodecID
Identify the syntax and semantics of the bitstream.
@ AV_CODEC_ID_MPEG2VIDEO
preferred ID for MPEG-1/2 video decoding
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
#define AVERROR_EXTERNAL
Generic error in an external library.
#define AVERROR_EOF
End of file.
#define AV_LOG_TRACE
Extremely verbose debugging, useful for libav* development.
#define AV_LOG_WARNING
Something somehow does not look correct.
#define AV_LOG_VERBOSE
Detailed information.
#define AV_LOG_INFO
Standard information.
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
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 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.
#define AV_NOPTS_VALUE
Undefined timestamp value.
common internal API header
#define FF_DISABLE_DEPRECATION_WARNINGS
#define FF_ENABLE_DEPRECATION_WARNINGS
#define AV_OPT_FLAG_DECODING_PARAM
a generic parameter which can be set by the user for demuxing or decoding
#define AV_OPT_FLAG_VIDEO_PARAM
@ AV_PIX_FMT_YUYV422
packed YUV 4:2:2, 16bpp, Y0 Cb Y1 Cr
Describe the class of an AVClass context structure.
main external API structure.
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
int width
picture width / height.
AVRational sample_aspect_ratio
sample aspect ratio (0 if unknown) That is the width of a pixel divided by the height of the pixel.
const struct AVCodec * codec
uint8_t * extradata
some codecs need / can use extradata like Huffman tables.
const char * name
Name of the codec implementation.
This structure describes decoded (raw) audio or video data.
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
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.
int64_t pkt_duration
duration of the corresponding packet, expressed in AVStream->time_base units, 0 if unknown.
int64_t pkt_pos
reordered pos from the last AVPacket that has been input into the decoder
int pkt_size
size of the corresponding packet containing the compressed frame.
int top_field_first
If the content is interlaced, is top field displayed first.
int interlaced_frame
The content of the picture is interlaced.
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
This structure stores compressed data.
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Rational number (pair of numerator and denominator).
uint8_t need_second_field
uint64_t reordered_opaque