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)