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>
68 #define OUTPUT_PROC_TIMEOUT 50
70 #define TIMESTAMP_UNIT 100000
115 {
"crystalhd_downscale_width",
116 "Turn on downscaling to the specified width",
132 return BC_MSUBTYPE_DIVX;
134 return BC_MSUBTYPE_DIVX311;
136 return BC_MSUBTYPE_MPEG2VIDEO;
138 return BC_MSUBTYPE_VC1;
140 return BC_MSUBTYPE_WMV3;
142 return priv->
is_nal ? BC_MSUBTYPE_AVC1 : BC_MSUBTYPE_H264;
144 return BC_MSUBTYPE_INVALID;
152 output->YBuffDoneSz);
154 output->UVBuffDoneSz);
156 output->PicInfo.timeStamp);
158 output->PicInfo.picture_number);
160 output->PicInfo.width);
162 output->PicInfo.height);
164 output->PicInfo.chroma_format);
166 output->PicInfo.pulldown);
168 output->PicInfo.flags);
170 output->PicInfo.frame_rate);
172 output->PicInfo.aspect_ratio);
174 output->PicInfo.colour_primaries);
176 output->PicInfo.picture_meta_payload);
178 output->PicInfo.sess_num);
180 output->PicInfo.ycom);
182 output->PicInfo.custom_aspect_ratio_width_height);
184 output->PicInfo.n_drop);
186 output->PicInfo.other.h264.valid);
199 "Unable to allocate new node in OpaqueList.\n");
204 priv->
head = newNode;
209 priv->
tail = newNode;
228 "CrystalHD: Attempted to query non-existent timestamps.\n");
266 "CrystalHD: Couldn't match fake_timestamp.\n");
283 DtsFlushInput(priv->
dev, 4);
293 DtsStopDecoder(device);
294 DtsCloseDecoder(device);
295 DtsDeviceClose(device);
334 void *extradata =
NULL;
340 "Cannot open the %s BSF!\n", bsf_name);
367 "Failed to allocate copy of extradata\n");
384 BC_INPUT_FORMAT
format = {
387 .OptFlags = 0x80000000 | vdecFrameRate59_94 | 0x40,
388 .width = avctx->
width,
392 BC_MEDIA_SUBTYPE subtype;
394 uint32_t
mode = DTS_PLAYBACK_MODE |
395 DTS_LOAD_FILE_PLAY_FW |
396 DTS_SKIP_TX_CHK_CPB |
397 DTS_PLAYBACK_DROP_RPT_MODE |
398 DTS_SINGLE_THREADED_MODE |
399 DTS_DFLT_RESOLUTION(vdecRESOLUTION_1080p23_976);
414 case BC_MSUBTYPE_AVC1:
415 avret =
init_bsf(avctx,
"h264_mp4toannexb");
419 subtype = BC_MSUBTYPE_H264;
420 format.startCodeSz = 4;
424 case BC_MSUBTYPE_H264:
425 format.startCodeSz = 4;
427 case BC_MSUBTYPE_VC1:
428 case BC_MSUBTYPE_WVC1:
429 case BC_MSUBTYPE_WMV3:
430 case BC_MSUBTYPE_WMVA:
431 case BC_MSUBTYPE_MPEG2VIDEO:
432 case BC_MSUBTYPE_DIVX:
433 case BC_MSUBTYPE_DIVX311:
441 format.mSubtype = subtype;
444 format.bEnableScaling = 1;
445 format.ScalingParams.sWidth = priv->
sWidth;
451 ret = DtsDeviceOpen(&priv->
dev, mode);
452 if (ret != BC_STS_SUCCESS) {
457 ret = DtsCrystalHDVersion(priv->
dev, &version);
458 if (ret != BC_STS_SUCCESS) {
460 "CrystalHD: DtsCrystalHDVersion failed\n");
463 priv->
is_70012 = version.device == 0;
466 (subtype == BC_MSUBTYPE_DIVX || subtype == BC_MSUBTYPE_DIVX311)) {
468 "CrystalHD: BCM70012 doesn't support MPEG4-ASP/DivX/Xvid\n");
472 ret = DtsSetInputFormat(priv->
dev, &format);
473 if (ret != BC_STS_SUCCESS) {
478 ret = DtsOpenDecoder(priv->
dev, BC_STREAM_TYPE_ES);
479 if (ret != BC_STS_SUCCESS) {
484 ret = DtsSetColorSpace(priv->
dev, OUTPUT_MODE422_YUY2);
485 if (ret != BC_STS_SUCCESS) {
489 ret = DtsStartDecoder(priv->
dev);
490 if (ret != BC_STS_SUCCESS) {
494 ret = DtsStartCapture(priv->
dev);
495 if (ret != BC_STS_SUCCESS) {
511 BC_DTS_PROC_OUT *output,
515 BC_DTS_STATUS decoder_status = { 0, };
521 uint8_t bottom_field = (output->PicInfo.flags & VDEC_FLAG_BOTTOMFIELD) ==
522 VDEC_FLAG_BOTTOMFIELD;
523 uint8_t bottom_first = !!(output->PicInfo.flags & VDEC_FLAG_BOTTOM_FIRST);
525 int width = output->PicInfo.width;
526 int height = output->PicInfo.height;
533 if (output->PicInfo.timeStamp != 0) {
548 output->PicInfo.timeStamp);
551 ret = DtsGetDriverStatus(priv->
dev, &decoder_status);
552 if (ret != BC_STS_SUCCESS) {
554 "CrystalHD: GetDriverStatus failed: %u\n", ret);
558 interlaced = output->PicInfo.flags & VDEC_FLAG_INTERLACED_SRC;
565 if (!frame->
data[0]) {
579 else if (width <= 1280)
590 dst = frame->
data[0];
601 *((uint32_t *)src) = *((uint32_t *)(src + sStride));
616 for (sY = 0; sY <
height; dY++, sY++) {
617 memcpy(&(dst[dY * dStride]), &(src[sY * sStride]), bwidth);
629 frame->
pts = pkt_pts;
654 BC_DTS_PROC_OUT output = {
655 .PicInfo.width = avctx->
width,
656 .PicInfo.height = avctx->
height,
665 if (ret == BC_STS_FMT_CHANGE) {
667 avctx->
width = output.PicInfo.width;
668 avctx->
height = output.PicInfo.height;
669 switch ( output.PicInfo.aspect_ratio ) {
670 case vdecAspectRatioSquare:
673 case vdecAspectRatio12_11:
676 case vdecAspectRatio10_11:
679 case vdecAspectRatio16_11:
682 case vdecAspectRatio40_33:
685 case vdecAspectRatio24_11:
688 case vdecAspectRatio20_11:
691 case vdecAspectRatio32_11:
694 case vdecAspectRatio80_33:
697 case vdecAspectRatio18_11:
700 case vdecAspectRatio15_11:
703 case vdecAspectRatio64_33:
706 case vdecAspectRatio160_99:
709 case vdecAspectRatio4_3:
712 case vdecAspectRatio16_9:
715 case vdecAspectRatio221_1:
720 }
else if (ret == BC_STS_SUCCESS) {
722 if (output.PoutFlags & BC_POUT_FLAGS_PIB_VALID) {
724 output.PicInfo.timeStamp == 0 && priv->
bframe_bug) {
727 "CrystalHD: Not returning packed frame twice.\n");
735 copy_ret =
copy_frame(avctx, &output, frame, got_frame);
747 }
else if (ret == BC_STS_BUSY) {
765 if (avpkt && avpkt->
size) {
773 "CrystalHD: Enabling work-around for packed b-frame bug\n");
780 "CrystalHD: Disabling work-around for packed b-frame bug\n");
790 "failed to ref input packet\n");
797 "failed to send input packet\n");
804 "failed to receive output packet\n");
808 avpkt = &filtered_packet;
812 if (avpkt->
size < tx_free) {
828 "input \"pts\": %"PRIu64
"\n", pts);
829 bc_ret = DtsProcInput(dev, avpkt->
data, avpkt->
size, pts, 0);
830 if (bc_ret == BC_STS_BUSY) {
832 "CrystalHD: ProcInput returned busy\n");
835 }
else if (bc_ret != BC_STS_SUCCESS) {
837 "CrystalHD: ProcInput failed: %u\n", ret);
860 BC_DTS_STATUS decoder_status = { 0, };
869 bc_ret = DtsGetDriverStatus(dev, &decoder_status);
870 if (bc_ret != BC_STS_SUCCESS) {
875 if (decoder_status.ReadyListCount == 0) {
887 }
else if (got_frame == 0) {
894 #define DEFINE_CRYSTALHD_DECODER(x, X) \
895 static const AVClass x##_crystalhd_class = { \
896 .class_name = #x "_crystalhd", \
897 .item_name = av_default_item_name, \
899 .version = LIBAVUTIL_VERSION_INT, \
901 AVCodec ff_##x##_crystalhd_decoder = { \
902 .name = #x "_crystalhd", \
903 .long_name = NULL_IF_CONFIG_SMALL("CrystalHD " #X " decoder"), \
904 .type = AVMEDIA_TYPE_VIDEO, \
905 .id = AV_CODEC_ID_##X, \
906 .priv_data_size = sizeof(CHDContext), \
907 .priv_class = &x##_crystalhd_class, \
910 .send_packet = crystalhd_decode_packet, \
911 .receive_frame = crystalhd_receive_frame, \
913 .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AVOID_PROBING, \
914 .pix_fmts = (const enum AVPixelFormat[]){AV_PIX_FMT_YUYV422, AV_PIX_FMT_NONE}, \
917 #if CONFIG_H264_CRYSTALHD_DECODER
921 #if CONFIG_MPEG2_CRYSTALHD_DECODER
925 #if CONFIG_MPEG4_CRYSTALHD_DECODER
929 #if CONFIG_MSMPEG4_CRYSTALHD_DECODER
933 #if CONFIG_VC1_CRYSTALHD_DECODER
937 #if CONFIG_WMV3_CRYSTALHD_DECODER
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.
#define AV_LOG_WARNING
Something somehow does not look correct.
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)
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)
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.
int av_bsf_receive_packet(AVBSFContext *ctx, AVPacket *pkt)
Retrieve a filtered packet.
static av_cold int uninit(AVCodecContext *avctx)
#define DEFINE_CRYSTALHD_DECODER(x, X)
#define AV_LOG_TRACE
Extremely verbose debugging, useful for libav* development.
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.
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.
static int crystalhd_receive_frame(AVCodecContext *avctx, AVFrame *frame)
static void flush(AVCodecContext *avctx)
const char * name
Name of the codec implementation.
int extradata_size
Size of the extradata content in bytes.
static void print_frame_info(CHDContext *priv, BC_DTS_PROC_OUT *output)
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_frame_set_pkt_pos(AVFrame *frame, int64_t val)
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.
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 int64_t pts
Global timestamp for the audio frames.
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 AV_INPUT_BUFFER_PADDING_SIZE
Required number of additionally allocated bytes at the end of the input bitstream for decoding...
#define FF_ENABLE_DEPRECATION_WARNINGS
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.
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.
This structure stores compressed data.
AVCodecParameters * par_in
Parameters of the input stream.
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.