|
MythTV
0.26-pre
|
00001 #include "privatedecoder_crystalhd.h" 00002 #include "myth_imgconvert.h" 00003 #include "mythlogging.h" 00004 00005 #define LOC QString("CrystalHD: ") 00006 #define ERR QString("CrystalHD Err: ") 00007 #define WARN QString("CrystalHD Warn: ") 00008 00009 void FetcherThread::run(void) 00010 { 00011 RunProlog(); 00012 LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("Starting Fetcher thread.")); 00013 if (m_dec) 00014 m_dec->FetchFrames(); 00015 LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("Stopping Fetcher thread.")); 00016 RunEpilog(); 00017 } 00018 00019 PixelFormat bcmpixfmt_to_pixfmt(BC_OUTPUT_FORMAT fmt); 00020 QString device_to_string(BC_DEVICE_TYPE device); 00021 QString bcmerr_to_string(BC_STATUS err); 00022 QString bcmpixfmt_to_string(BC_OUTPUT_FORMAT fmt); 00023 QString pulldown_to_string(int pulldown); 00024 QString decoderflags_to_string(int flags); 00025 QString poutflags_to_string(int flags); 00026 00027 #define INIT_ST BC_STATUS st; bool ok = true 00028 #define CHECK_ST \ 00029 ok &= (st == BC_STS_SUCCESS); \ 00030 if (!ok) \ 00031 LOG(VB_GENERAL, LOG_ERR, LOC + QString("Error at %1:%2 (#%3, %4)") \ 00032 .arg(__FILE__).arg( __LINE__).arg(st) \ 00033 .arg(bcmerr_to_string(st))) 00034 00035 void PrivateDecoderCrystalHD::GetDecoders(render_opts &opts) 00036 { 00037 opts.decoders->append("crystalhd"); 00038 (*opts.equiv_decoders)["crystalhd"].append("nuppel"); 00039 (*opts.equiv_decoders)["crystalhd"].append("ffmpeg"); 00040 (*opts.equiv_decoders)["crystalhd"].append("dummy"); 00041 } 00042 00043 PrivateDecoderCrystalHD::PrivateDecoderCrystalHD() 00044 : m_device(NULL), m_device_type(BC_70012), 00045 m_pix_fmt(OUTPUT_MODE_INVALID), m_decoded_frames_lock(QMutex::Recursive), 00046 m_fetcher_thread(NULL), m_fetcher_pause(false), m_fetcher_paused(false), 00047 m_fetcher_stop(false), m_frame(NULL), m_filter(NULL) 00048 { 00049 } 00050 00051 PrivateDecoderCrystalHD::~PrivateDecoderCrystalHD() 00052 { 00053 if (m_fetcher_thread) 00054 { 00055 m_fetcher_pause = true; 00056 m_fetcher_stop = true; 00057 int tries = 0; 00058 while (!m_fetcher_thread->wait(100) && (tries++ < 50)) 00059 LOG(VB_PLAYBACK, LOG_WARNING, LOC + 00060 "Waited 100ms for Fetcher to stop"); 00061 00062 if (m_fetcher_thread->isRunning()) 00063 LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to stop Fetcher."); 00064 else 00065 LOG(VB_PLAYBACK, LOG_INFO, LOC + "Stopped frame Fetcher."); 00066 delete m_fetcher_thread; 00067 } 00068 00069 if (m_filter) 00070 av_bitstream_filter_close(m_filter); 00071 00072 Reset(); 00073 if (!m_device) 00074 return; 00075 00076 INIT_ST; 00077 if (m_device_type != BC_70015) 00078 { 00079 st = DtsFlushRxCapture(m_device, false); 00080 CHECK_ST; 00081 } 00082 st = DtsStopDecoder(m_device); 00083 CHECK_ST; 00084 st = DtsCloseDecoder(m_device); 00085 CHECK_ST; 00086 DtsDeviceClose(m_device); 00087 } 00088 00089 bool PrivateDecoderCrystalHD::Init(const QString &decoder, 00090 PlayerFlags flags, 00091 AVCodecContext *avctx) 00092 { 00093 if ((decoder != "crystalhd") || !(flags & kDecodeAllowEXT) || 00094 !avctx || getenv("NO_CRYSTALHD")) 00095 return false; 00096 00097 static bool debugged = false; 00098 00099 uint32_t well_documented = DTS_PLAYBACK_MODE | DTS_LOAD_FILE_PLAY_FW | 00100 DTS_SKIP_TX_CHK_CPB | 00101 DTS_PLAYBACK_DROP_RPT_MODE | 00102 DTS_DFLT_RESOLUTION(vdecRESOLUTION_CUSTOM); 00103 INIT_ST; 00104 st = DtsDeviceOpen(&m_device, well_documented); 00105 CHECK_ST; 00106 if (!ok) 00107 { 00108 LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to open CrystalHD device"); 00109 return false; 00110 } 00111 00112 _BC_INFO_CRYSTAL_ info; 00113 st = DtsCrystalHDVersion(m_device, &info); 00114 CHECK_ST; 00115 if (!ok) 00116 { 00117 LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to get device info."); 00118 return false; 00119 } 00120 00121 m_device_type = (BC_DEVICE_TYPE)info.device; 00122 00123 if (!debugged) 00124 { 00125 LOG(VB_GENERAL, LOG_INFO, LOC + QString("Device: %1") 00126 .arg(device_to_string(m_device_type))); 00127 LOG(VB_GENERAL, LOG_INFO, LOC + QString("Library : %1.%2.%3") 00128 .arg(info.dilVersion.dilMajor) 00129 .arg(info.dilVersion.dilMinor) 00130 .arg(info.dilVersion.version)); 00131 LOG(VB_GENERAL, LOG_INFO, LOC + QString("Driver : %1.%2.%3") 00132 .arg(info.drvVersion.drvMajor) 00133 .arg(info.drvVersion.drvMinor) 00134 .arg(info.drvVersion.version)); 00135 LOG(VB_GENERAL, LOG_INFO, LOC + QString("Firmware: %1.%2.%3") 00136 .arg(info.fwVersion.fwMajor) 00137 .arg(info.fwVersion.fwMinor) 00138 .arg(info.fwVersion.version)); 00139 } 00140 00141 if (BC_70012 == m_device_type) 00142 { 00143 LOG(VB_GENERAL, LOG_ERR, LOC + 00144 "BCM70012 device is currently unsupported."); 00145 return false; 00146 } 00147 00148 BC_HW_CAPS hw_caps; 00149 uint32_t codecs; 00150 st = DtsGetCapabilities(m_device, &hw_caps); 00151 CHECK_ST; 00152 if (!ok) 00153 { 00154 LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to get device capabilities"); 00155 return false; 00156 } 00157 00158 BC_OUTPUT_FORMAT m_desired_fmt = (m_device_type == BC_70015) ? 00159 OUTPUT_MODE422_YUY2 : OUTPUT_MODE420; 00160 m_pix_fmt = OUTPUT_MODE_INVALID; 00161 for (int i = 0; i < hw_caps.ColorCaps.Count; i++) 00162 { 00163 if (m_desired_fmt == hw_caps.ColorCaps.OutFmt[i]) 00164 m_pix_fmt = m_desired_fmt; 00165 if (!debugged) 00166 { 00167 LOG(VB_PLAYBACK, LOG_INFO, LOC + 00168 QString("Supported output format: %1") 00169 .arg(bcmpixfmt_to_string(hw_caps.ColorCaps.OutFmt[i]))); 00170 } 00171 } 00172 if (m_pix_fmt != m_desired_fmt) 00173 { 00174 LOG(VB_PLAYBACK, LOG_ERR, LOC + 00175 "Failed to find correct output format."); 00176 return false; 00177 } 00178 LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("Using: %1") 00179 .arg(bcmpixfmt_to_string(m_pix_fmt))); 00180 00181 codecs = hw_caps.DecCaps; 00182 if (!debugged) 00183 { 00184 LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("H.264 support: %1") 00185 .arg((bool)(codecs & BC_DEC_FLAGS_H264))); 00186 LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("MPEG2 support: %1") 00187 .arg((bool)(codecs & BC_DEC_FLAGS_MPEG2))); 00188 LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("VC1 support: %1") 00189 .arg((bool)(codecs & BC_DEC_FLAGS_VC1))); 00190 LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("MPEG4 support: %1") 00191 .arg((bool)(codecs & BC_DEC_FLAGS_M4P2))); 00192 debugged = true; 00193 } 00194 00195 BC_MEDIA_SUBTYPE sub_type = BC_MSUBTYPE_INVALID; 00196 00197 switch (avctx->codec_id) 00198 { 00199 case CODEC_ID_MPEG4: 00200 if (codecs & BC_DEC_FLAGS_M4P2) 00201 sub_type = BC_MSUBTYPE_DIVX; 00202 break; 00203 case CODEC_ID_MPEG1VIDEO: 00204 if (codecs & BC_DEC_FLAGS_MPEG2) 00205 sub_type = BC_MSUBTYPE_MPEG1VIDEO; 00206 break; 00207 case CODEC_ID_MPEG2VIDEO: 00208 if (codecs & BC_DEC_FLAGS_MPEG2) 00209 sub_type = BC_MSUBTYPE_MPEG2VIDEO; 00210 break; 00211 case CODEC_ID_VC1: 00212 if (codecs & BC_DEC_FLAGS_VC1) 00213 { 00214 if (avctx->codec_tag == MKTAG('W','V','C','1')) 00215 sub_type = BC_MSUBTYPE_WVC1; 00216 else 00217 sub_type = BC_MSUBTYPE_VC1; 00218 } 00219 break; 00220 case CODEC_ID_WMV3: 00221 if (codecs & BC_DEC_FLAGS_VC1) 00222 sub_type = BC_MSUBTYPE_WMV3; 00223 break; 00224 case CODEC_ID_H264: 00225 if (codecs & BC_DEC_FLAGS_H264) 00226 { 00227 if (avctx->extradata[0] == 0x01) 00228 { 00229 if (!CreateFilter(avctx)) 00230 { 00231 LOG(VB_PLAYBACK, LOG_ERR, LOC + 00232 "Failed to create stream filter"); 00233 return false; 00234 } 00235 sub_type = BC_MSUBTYPE_AVC1; 00236 } 00237 else 00238 sub_type = BC_MSUBTYPE_H264; 00239 } 00240 break; 00241 } 00242 00243 if (sub_type == BC_MSUBTYPE_INVALID) 00244 { 00245 LOG(VB_PLAYBACK, LOG_ERR, LOC + QString("Codec %1 not supported") 00246 .arg(ff_codec_id_string(avctx->codec_id))); 00247 return false; 00248 } 00249 00250 int nalsize = 4; 00251 if (avctx->codec_id == CODEC_ID_H264) 00252 { 00253 LOG(VB_PLAYBACK, LOG_INFO, LOC + 00254 QString("H.264 Profile: %1 RefFrames: %2 Codec tag: %3") 00255 .arg(avctx->profile).arg(avctx->refs) 00256 .arg(fourcc_str(avctx->codec_tag))); 00257 if (avctx->extradata[0] == 1) 00258 { 00259 nalsize = (avctx->extradata[4] & 0x03) + 1; 00260 LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("avcC nal size: %1") 00261 .arg(nalsize)); 00262 } 00263 } 00264 00265 BC_INPUT_FORMAT fmt; 00266 memset(&fmt, 0, sizeof(BC_INPUT_FORMAT)); 00267 fmt.OptFlags = 0x80000000 | vdecFrameRateUnknown; 00268 fmt.width = avctx->coded_width; 00269 fmt.height = avctx->coded_height; 00270 fmt.Progressive = 1; 00271 fmt.FGTEnable = 0; 00272 fmt.MetaDataEnable = 0; 00273 fmt.metaDataSz = avctx->extradata_size; 00274 fmt.pMetaData = avctx->extradata; 00275 fmt.startCodeSz = nalsize; 00276 fmt.mSubtype = sub_type; 00277 00278 st = DtsSetInputFormat(m_device, &fmt); 00279 CHECK_ST; 00280 if (!ok) 00281 { 00282 LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to set decoder input format"); 00283 return false; 00284 } 00285 00286 st = DtsOpenDecoder(m_device, BC_STREAM_TYPE_ES); 00287 CHECK_ST; 00288 if (!ok) 00289 { 00290 LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to open CrystalHD decoder"); 00291 return false; 00292 } 00293 00294 st = DtsSetColorSpace(m_device, m_pix_fmt); 00295 if (!ok) 00296 { 00297 LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to set decoder output format"); 00298 return false; 00299 } 00300 00301 st = DtsStartDecoder(m_device); 00302 if (!ok) 00303 { 00304 LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to start decoder"); 00305 return false; 00306 } 00307 00308 st = DtsStartCapture(m_device); 00309 if (!ok) 00310 { 00311 LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to start capture"); 00312 return false; 00313 } 00314 00315 Reset(); 00316 00317 LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("Created decoder %1 %2x%3") 00318 .arg(ff_codec_id_string(avctx->codec_id)) 00319 .arg(avctx->coded_width).arg(avctx->coded_height)); 00320 return true; 00321 } 00322 00323 bool PrivateDecoderCrystalHD::CreateFilter(AVCodecContext *avctx) 00324 { 00325 int nalsize = (avctx->extradata[4] & 0x3) + 1; 00326 if (!nalsize || nalsize == 3 || nalsize > 4) 00327 { 00328 LOG(VB_PLAYBACK, LOG_ERR, LOC + QString("Invalid nal size (%1)") 00329 .arg(nalsize)); 00330 return false; 00331 } 00332 00333 static const uint8_t testnal[] = { 0,0,0,2,0,0 }; 00334 AVBitStreamFilterContext *bsfc = 00335 av_bitstream_filter_init("h264_mp4toannexb"); 00336 if (!bsfc) 00337 return false; 00338 m_filter = bsfc; 00339 00340 // and test extradata 00341 const uint8_t *test = testnal; 00342 int testsize = 6; 00343 int outbuf_size = 0; 00344 uint8_t *outbuf = NULL; 00345 int res = av_bitstream_filter_filter(m_filter, avctx, NULL, &outbuf, 00346 &outbuf_size, test, testsize, 0); 00347 delete outbuf; 00348 return res > 0; 00349 } 00350 00351 void inline free_frame(VideoFrame* frame) 00352 { 00353 if (frame) 00354 { 00355 if (frame->buf) 00356 delete [] frame->buf; 00357 if (frame->priv[0]) 00358 delete [] frame->priv[0]; 00359 delete frame; 00360 } 00361 } 00362 00363 void inline free_buffer(PacketBuffer* buffer) 00364 { 00365 if (buffer) 00366 { 00367 if (buffer->buf) 00368 delete [] buffer->buf; 00369 delete buffer; 00370 } 00371 } 00372 00373 bool PrivateDecoderCrystalHD::Reset(void) 00374 { 00375 if (m_fetcher_thread) 00376 { 00377 m_fetcher_pause = true; 00378 int tries = 0; 00379 while (!m_fetcher_paused && (tries++ < 50)) 00380 usleep(10000); 00381 if (!m_fetcher_paused) 00382 LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to pause fetcher thread"); 00383 } 00384 00385 QMutexLocker lock(&m_decoded_frames_lock); 00386 free_frame(m_frame); 00387 m_frame = NULL; 00388 00389 for (int i = 0; i < m_decoded_frames.size(); i++) 00390 free_frame(m_decoded_frames[i]); 00391 m_decoded_frames.clear(); 00392 00393 for (int i = 0; i < m_packet_buffers.size(); i++) 00394 free_buffer(m_packet_buffers[i]); 00395 m_packet_buffers.clear(); 00396 00397 if (!m_device) 00398 return true; 00399 00400 if (m_device_type != BC_70015) 00401 { 00402 INIT_ST; 00403 st = DtsFlushInput(m_device, 2); 00404 CHECK_ST; 00405 } 00406 return true;; 00407 } 00408 00409 bool PrivateDecoderCrystalHD::HasBufferedFrames(void) 00410 { 00411 m_decoded_frames_lock.lock(); 00412 bool result = m_decoded_frames.size() > 0; 00413 m_decoded_frames_lock.unlock(); 00414 return result; 00415 } 00416 00417 int PrivateDecoderCrystalHD::ProcessPacket(AVStream *stream, AVPacket *pkt) 00418 { 00419 int result = -1; 00420 AVCodecContext *avctx = stream->codec; 00421 if (!avctx) 00422 return result; 00423 00424 PacketBuffer *buffer = new PacketBuffer(); 00425 if (!buffer) 00426 return result; 00427 00428 buffer->buf = new unsigned char[pkt->size]; 00429 buffer->size = pkt->size; 00430 buffer->pts = pkt->pts; 00431 memcpy(buffer->buf, pkt->data, pkt->size); 00432 00433 m_packet_buffers.insert(0, buffer); 00434 LOG(VB_PLAYBACK, LOG_DEBUG, LOC + 00435 QString("%1 packet buffers queued up").arg(m_packet_buffers.size())); 00436 00437 while (m_packet_buffers.size() > 0) 00438 { 00439 00440 PacketBuffer *buffer = m_packet_buffers.last(); 00441 if (GetTxFreeSize(0) < buffer->size) 00442 { 00443 usleep(10000); 00444 return 0; 00445 } 00446 00447 buffer = m_packet_buffers.takeLast(); 00448 uint8_t* buf = buffer->buf; 00449 int size = buffer->size; 00450 bool free_buf = false; 00451 int outbuf_size = 0; 00452 uint8_t *outbuf = NULL; 00453 00454 if (m_filter) 00455 { 00456 int res = av_bitstream_filter_filter(m_filter, avctx, NULL, &outbuf, 00457 &outbuf_size, buf, size, 0); 00458 if (res <= 0) 00459 { 00460 static int count = 0; 00461 if (count == 0) 00462 LOG(VB_GENERAL, LOG_ERR, LOC + 00463 QString("Failed to convert packet (%1)").arg(res)); 00464 count++; 00465 if (count > 200) 00466 count = 0; 00467 } 00468 00469 if (outbuf && (outbuf_size > 0)) 00470 { 00471 free_buf = outbuf != buf; 00472 size = outbuf_size; 00473 buf = outbuf; 00474 } 00475 } 00476 00477 usleep(1000); 00478 uint64_t chd_timestamp = 0; // 100 nsec units 00479 if (buffer->pts != (int64_t)AV_NOPTS_VALUE) 00480 chd_timestamp = (uint64_t)(av_q2d(stream->time_base) * 00481 buffer->pts * 10000000); 00482 LOG(VB_TIMESTAMP, LOG_DEBUG, LOC + 00483 QString("decoder input timecode %1 ms (pts %2)") 00484 .arg(chd_timestamp / 10000).arg(buffer->pts)); 00485 00486 // TODO check for busy state 00487 INIT_ST; 00488 st = DtsProcInput(m_device, buf, size, chd_timestamp, false); 00489 CHECK_ST; 00490 00491 if (free_buf) 00492 delete buf; 00493 00494 free_buffer(buffer); 00495 if (!ok) 00496 LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to send packet to decoder."); 00497 result = buffer->size; 00498 } 00499 return result; 00500 } 00501 00502 int PrivateDecoderCrystalHD::GetFrame(AVStream *stream, 00503 AVFrame *picture, 00504 int *got_picture_ptr, 00505 AVPacket *pkt) 00506 { 00507 int result = -1; 00508 if (!stream || !m_device || !picture) 00509 return result; 00510 00511 AVCodecContext *avctx = stream->codec; 00512 if (!avctx || !StartFetcherThread()) 00513 return result; 00514 00515 if (pkt && pkt->size) 00516 { 00517 result = ProcessPacket(stream, pkt); 00518 if (result < 0) 00519 return result; 00520 } 00521 00522 m_decoded_frames_lock.lock(); 00523 int available = m_decoded_frames.size(); 00524 m_decoded_frames_lock.unlock(); 00525 if (!available) 00526 return result; 00527 00528 if (avctx->get_buffer(avctx, picture) < 0) 00529 { 00530 LOG(VB_GENERAL, LOG_ERR, LOC + 00531 QString("%1 decoded frames available but no video buffers.") 00532 .arg(available)); 00533 return -1; 00534 } 00535 00536 m_decoded_frames_lock.lock(); 00537 VideoFrame *frame = m_decoded_frames.takeLast(); 00538 m_decoded_frames_lock.unlock(); 00539 00540 *got_picture_ptr = 1; 00541 picture->reordered_opaque = (int64_t)(frame->timecode / 00542 av_q2d(stream->time_base) / 10000000); 00543 LOG(VB_TIMESTAMP, LOG_DEBUG, LOC + 00544 QString("decoder output timecode %1 ms (pts %2)") 00545 .arg(frame->timecode / 10000).arg(picture->reordered_opaque)); 00546 copy((VideoFrame*)picture->opaque, frame); 00547 if (frame->priv[0] && frame->qstride) 00548 { 00549 memcpy(picture->atsc_cc_buf, frame->priv[0], frame->qstride); 00550 picture->atsc_cc_len = frame->qstride; 00551 } 00552 free_frame(frame); 00553 return result; 00554 } 00555 00556 void PrivateDecoderCrystalHD::FetchFrames(void) 00557 { 00558 INIT_ST; 00559 bool valid = false; 00560 m_fetcher_paused = false; 00561 while (!m_fetcher_stop) 00562 { 00563 usleep(1000); 00564 if (m_fetcher_pause) 00565 { 00566 m_fetcher_paused = true; 00567 continue; 00568 } 00569 m_fetcher_paused = false; 00570 00571 BC_DTS_STATUS status; 00572 st = DtsGetDriverStatus(m_device, &status); 00573 CHECK_ST; 00574 00575 if (!status.ReadyListCount) 00576 continue; 00577 00578 BC_DTS_PROC_OUT out; 00579 memset(&out, 0, sizeof(BC_DTS_PROC_OUT)); 00580 st = DtsProcOutputNoCopy(m_device, valid ? 2000 : 20, &out); 00581 00582 if (BC_STS_FMT_CHANGE == st) 00583 { 00584 LOG(VB_GENERAL, LOG_INFO, LOC + "Decoder reported format change."); 00585 CheckProcOutput(&out); 00586 valid = true; 00587 continue; 00588 } 00589 CHECK_ST; 00590 00591 if (!ok) 00592 { 00593 LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to fetch decoded frame"); 00594 continue; 00595 } 00596 00597 if (ok && valid && (out.PoutFlags & BC_POUT_FLAGS_PIB_VALID)) 00598 FillFrame(&out); 00599 st = DtsReleaseOutputBuffs(m_device, NULL, false); 00600 CHECK_ST; 00601 } 00602 } 00603 00604 bool PrivateDecoderCrystalHD::StartFetcherThread(void) 00605 { 00606 m_fetcher_pause = false; 00607 if (m_fetcher_thread) 00608 return true; 00609 00610 m_fetcher_thread = new FetcherThread(this); 00611 if (!m_fetcher_thread) 00612 return false; 00613 00614 m_fetcher_thread->start(); 00615 return true; 00616 } 00617 00618 00619 void PrivateDecoderCrystalHD::FillFrame(BC_DTS_PROC_OUT *out) 00620 { 00621 bool second_field = false; 00622 if (m_frame) 00623 { 00624 if (out->PicInfo.picture_number != m_frame->frameNumber) 00625 { 00626 LOG(VB_PLAYBACK, LOG_WARNING, LOC + "Missing second field"); 00627 AddFrameToQueue(); 00628 } 00629 else 00630 { 00631 second_field = true; 00632 } 00633 } 00634 00635 int in_width = out->PicInfo.width; 00636 int in_height = out->PicInfo.height; 00637 int out_width = (in_width + 15) & (~0xf); 00638 int out_height = in_height; 00639 int size = ((out_width * (out_height + 1)) * 3) / 2; 00640 uint8_t* src = out->Ybuff; 00641 00642 if (!m_frame) 00643 { 00644 unsigned char* buf = new unsigned char[size]; 00645 m_frame = new VideoFrame(); 00646 init(m_frame, FMT_YV12, buf, out_width, out_height, size); 00647 m_frame->timecode = (int64_t)out->PicInfo.timeStamp; 00648 m_frame->frameNumber = out->PicInfo.picture_number; 00649 } 00650 00651 if (!m_frame) 00652 return; 00653 00654 // line 21 data (608/708 captions) 00655 // this appears to be unimplemented in the driver 00656 if (out->UserData && out->UserDataSz) 00657 { 00658 int size = out->UserDataSz > 1024 ? 1024 : out->UserDataSz; 00659 m_frame->priv[0] = new unsigned char[size]; 00660 memcpy(m_frame->priv[0], out->UserData, size); 00661 m_frame->qstride = size; // don't try this at home 00662 } 00663 00664 PixelFormat out_fmt = PIX_FMT_YUV420P; 00665 PixelFormat in_fmt = bcmpixfmt_to_pixfmt(m_pix_fmt); 00666 AVPicture img_in, img_out; 00667 avpicture_fill(&img_out, (uint8_t *)m_frame->buf, out_fmt, 00668 out_width, out_height); 00669 avpicture_fill(&img_in, src, in_fmt, 00670 in_width, in_height); 00671 00672 if (!(out->PicInfo.flags & VDEC_FLAG_INTERLACED_SRC)) 00673 { 00674 myth_sws_img_convert(&img_out, out_fmt, &img_in, in_fmt, 00675 in_width, in_height); 00676 m_frame->interlaced_frame = 0; 00677 AddFrameToQueue(); 00678 } 00679 else 00680 { 00681 img_out.linesize[0] *= 2; 00682 img_out.linesize[1] *= 2; 00683 img_out.linesize[2] *= 2; 00684 m_frame->top_field_first = out->PicInfo.pulldown == vdecTopBottom; 00685 int field = out->PoutFlags & BC_POUT_FLAGS_FLD_BOT; 00686 if (field) 00687 { 00688 img_out.data[0] += out_width; 00689 img_out.data[1] += out_width >> 1; 00690 img_out.data[2] += out_width >> 1; 00691 } 00692 myth_sws_img_convert(&img_out, out_fmt, &img_in, 00693 in_fmt, in_width, in_height / 2); 00694 if (second_field) 00695 AddFrameToQueue(); 00696 } 00697 } 00698 00699 void PrivateDecoderCrystalHD::AddFrameToQueue(void) 00700 { 00701 m_decoded_frames_lock.lock(); 00702 m_decoded_frames.insert(0, m_frame); 00703 LOG(VB_PLAYBACK, LOG_DEBUG, LOC + QString("Decoded frame queue size %1") 00704 .arg(m_decoded_frames.size())); 00705 m_decoded_frames_lock.unlock(); 00706 m_frame = NULL; 00707 } 00708 00709 void PrivateDecoderCrystalHD::CheckProcOutput(BC_DTS_PROC_OUT *out) 00710 { 00711 LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("ProcOut Ybuf : %1") 00712 .arg((uintptr_t)out->Ybuff)); 00713 LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("ProcOut Ybuffsz : %1") 00714 .arg(out->YbuffSz)); 00715 LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("ProcOut Ybuffdnsz : %1") 00716 .arg(out->YBuffDoneSz)); 00717 LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("ProcOut Ubuf : %1") 00718 .arg((uintptr_t)out->UVbuff)); 00719 LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("ProcOut Ubuffsz : %1") 00720 .arg(out->UVbuffSz)); 00721 LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("ProcOut Ubuffdnsz : %1") 00722 .arg(out->UVBuffDoneSz)); 00723 LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("ProcOut StrideSz : %1") 00724 .arg(out->StrideSz)); 00725 LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("ProcOut Flags : %1") 00726 .arg(poutflags_to_string(out->PoutFlags))); 00727 LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("ProcOut DiscCnt : %1") 00728 .arg(out->discCnt)); 00729 LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("ProcOut usrdatasz : %1") 00730 .arg(out->UserDataSz)); 00731 LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("ProcOut DropFrames: %1") 00732 .arg(out->DropFrames)); 00733 LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("ProcOut b422Mode : %1") 00734 .arg(bcmpixfmt_to_string((BC_OUTPUT_FORMAT)out->b422Mode))); 00735 LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("ProcOut bPIBenc : %1") 00736 .arg(out->bPibEnc)); 00737 LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("ProcOut revertscra: %1") 00738 .arg(out->bRevertScramble)); 00739 CheckPicInfo(out); 00740 } 00741 00742 void PrivateDecoderCrystalHD::CheckPicInfo(BC_DTS_PROC_OUT *out) 00743 { 00744 LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("ProcOut PicInfo timestamp: %1") 00745 .arg(out->PicInfo.timeStamp)); 00746 LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("ProcOut PicInfo picnumber: %1") 00747 .arg(out->PicInfo.picture_number)); 00748 LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("ProcOut PicInfo width : %1") 00749 .arg(out->PicInfo.width)); 00750 LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("ProcOut PicInfo height : %1") 00751 .arg(out->PicInfo.height)); 00752 LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("ProcOut PicInfo chromafmt: %1") 00753 .arg(out->PicInfo.chroma_format)); 00754 LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("ProcOut PicInfo pulldown : %1") 00755 .arg(pulldown_to_string(out->PicInfo.pulldown))); 00756 LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("ProcOut PicInfo flags : %1") 00757 .arg(decoderflags_to_string(out->PicInfo.flags))); 00758 LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("ProcOut PicInfo framerate: %1") 00759 .arg(out->PicInfo.frame_rate)); 00760 LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("ProcOut PicInfo aspectrat: %1") 00761 .arg(out->PicInfo.colour_primaries)); 00762 LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("ProcOut PicInfo metapaylo: %1") 00763 .arg(out->PicInfo.picture_meta_payload)); 00764 LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("ProcOut PicInfo sess_num : %1") 00765 .arg(out->PicInfo.sess_num)); 00766 LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("ProcOut PicInfo ycom : %1") 00767 .arg(out->PicInfo.ycom)); 00768 LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("ProcOut PicInfo customasp: %1") 00769 .arg(out->PicInfo.custom_aspect_ratio_width_height)); 00770 LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("ProcOut PicInfo ndrop : %1") 00771 .arg(out->PicInfo.n_drop)); 00772 } 00773 00774 void PrivateDecoderCrystalHD::CheckStatus(void) 00775 { 00776 BC_DTS_STATUS status; 00777 status.cpbEmptySize = 0x00000000; // set bit 31 for real HW free size 00778 INIT_ST; 00779 st = DtsGetDriverStatus(m_device, &status); 00780 CHECK_ST; 00781 if (!ok) 00782 return; 00783 00784 LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("ReadyListCount : %1") 00785 .arg(status.ReadyListCount)); 00786 LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("FreeListCount : %1") 00787 .arg(status.FreeListCount)); 00788 LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("PowerStateChange: %1") 00789 .arg(status.PowerStateChange)); 00790 LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("FrameDropped : %1") 00791 .arg(status.FramesDropped)); 00792 LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("FramesCaptured : %1") 00793 .arg(status.FramesCaptured)); 00794 LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("FramesRepeated : %1") 00795 .arg(status.FramesRepeated)); 00796 LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("InputCount : %1") 00797 .arg(status.InputCount)); 00798 LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("InputTotalSize : %1") 00799 .arg(status.InputTotalSize)); 00800 LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("InputBusyCount : %1") 00801 .arg(status.InputBusyCount)); 00802 LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("PIBMissCount : %1") 00803 .arg(status.PIBMissCount)); 00804 LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("cpbEmptySize : %1") 00805 .arg(status.cpbEmptySize)); 00806 LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("NextTimeStamp : %1") 00807 .arg(status.NextTimeStamp)); 00808 LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("PicNumFlags : %1") 00809 .arg(status.picNumFlags)); 00810 } 00811 00812 int PrivateDecoderCrystalHD::GetTxFreeSize(bool hwsel) 00813 { 00814 BC_DTS_STATUS status; 00815 if (hwsel) 00816 status.cpbEmptySize = 0xC0000000; // set bit 31 for real HW free size 00817 else 00818 status.cpbEmptySize = 0x40000000; // set bit 30 for TX only status 00819 INIT_ST; 00820 st = DtsGetDriverStatus(m_device, &status); 00821 CHECK_ST; 00822 if (!ok) 00823 return -1; 00824 00825 return status.cpbEmptySize; 00826 } 00827 00828 QString device_to_string(BC_DEVICE_TYPE device) 00829 { 00830 switch (device) 00831 { 00832 case BC_70012: return "BCM70012"; 00833 case BC_70015: return "BCM70015"; 00834 } 00835 return "Unknown"; 00836 } 00837 00838 QString bcmerr_to_string(BC_STATUS err) 00839 { 00840 switch (err) 00841 { 00842 case BC_STS_INV_ARG: return "Invalid argument"; 00843 case BC_STS_BUSY: return "Busy"; 00844 case BC_STS_NOT_IMPL: return "Not implemented"; 00845 case BC_STS_PGM_QUIT: return "PGM quit"; 00846 case BC_STS_NO_ACCESS: return "No access"; 00847 case BC_STS_INSUFF_RES: return "Insufficient resources"; 00848 case BC_STS_IO_ERROR: return "I/O error"; 00849 case BC_STS_NO_DATA: return "No data"; 00850 case BC_STS_VER_MISMATCH: return "Version mismatch"; 00851 case BC_STS_TIMEOUT: return "Timeout"; 00852 case BC_STS_FW_CMD_ERR: return "Command error"; 00853 case BC_STS_DEC_NOT_OPEN: return "Decoder not open"; 00854 case BC_STS_ERR_USAGE: return "Usage error"; 00855 case BC_STS_IO_USER_ABORT: return "I/O user abort"; 00856 case BC_STS_IO_XFR_ERROR: return "I/O transfer error"; 00857 case BC_STS_DEC_NOT_STARTED: return "Decoder not started"; 00858 case BC_STS_FWHEX_NOT_FOUND: return "FirmwareHex not found"; 00859 case BC_STS_FMT_CHANGE: return "Format change"; 00860 case BC_STS_HIF_ACCESS: return "HIF access"; 00861 case BC_STS_CMD_CANCELLED: return "Command cancelled"; 00862 case BC_STS_FW_AUTH_FAILED: return "Firmware authorisation failed"; 00863 case BC_STS_BOOTLOADER_FAILED: return "Bootloader failed"; 00864 case BC_STS_CERT_VERIFY_ERROR: return "Certificate verify error"; 00865 case BC_STS_DEC_EXIST_OPEN: return "Decoder exist open (?)"; 00866 case BC_STS_PENDING: return "Pending"; 00867 case BC_STS_ERROR: return "Unknown"; 00868 } 00869 return "Unknown error"; 00870 } 00871 00872 QString bcmpixfmt_to_string(BC_OUTPUT_FORMAT fmt) 00873 { 00874 switch (fmt) 00875 { 00876 case OUTPUT_MODE420: return "YUV420P"; 00877 case OUTPUT_MODE422_YUY2: return "YUYV422"; 00878 case OUTPUT_MODE422_UYVY: return "UYVY422"; 00879 } 00880 return "Unknown"; 00881 } 00882 00883 QString pulldown_to_string(int pulldown) 00884 { 00885 switch (pulldown) 00886 { 00887 case vdecNoPulldownInfo: return "Unknown"; 00888 case vdecTop: return "Top"; 00889 case vdecBottom: return "Bottom"; 00890 case vdecTopBottom: return "TopBottom"; 00891 case vdecBottomTop: return "BottomTop"; 00892 case vdecTopBottomTop: return "TopBottomTop"; 00893 case vdecBottomTopBottom: return "BottomTopBottom"; 00894 case vdecFrame_X2: return "X2"; 00895 case vdecFrame_X3: return "X3"; 00896 case vdecFrame_X1: return "X1"; 00897 case vdecFrame_X4: return "X4"; 00898 } 00899 return "Unknown"; 00900 } 00901 00902 QString decoderflags_to_string(int flags) 00903 { 00904 QString res; 00905 if (flags & VDEC_FLAG_EOS) res += "EndOfStream "; 00906 if (flags & VDEC_FLAG_FIELDPAIR) res += "FieldPair "; 00907 if (flags & VDEC_FLAG_TOPFIELD) res += "TopField "; 00908 if (flags & VDEC_FLAG_BOTTOMFIELD) res += "BottomField "; 00909 if (flags & VDEC_FLAG_INTERLACED_SRC) res += "InterlacedSource "; 00910 if (flags & VDEC_FLAG_UNKNOWN_SRC) res += "UnknownSource "; 00911 if (flags & VDEC_FLAG_BOTTOM_FIRST) res += "BottomFirst "; 00912 if (flags & VDEC_FLAG_LAST_PICTURE) res += "LastPicture "; 00913 if (flags & VDEC_FLAG_PICTURE_META_DATA_PRESENT) res += "MetaDataPresent "; 00914 return res; 00915 } 00916 00917 QString poutflags_to_string(int flags) 00918 { 00919 QString res; 00920 if (flags & BC_POUT_FLAGS_YV12) res += "YV12 "; 00921 if (flags & BC_POUT_FLAGS_STRIDE) res += "STRIDE "; 00922 if (flags & BC_POUT_FLAGS_SIZE) res += "SIZE "; 00923 if (flags & BC_POUT_FLAGS_INTERLACED) res += "INTERLACED "; 00924 if (flags & BC_POUT_FLAGS_INTERLEAVED) res += "INTERLEAVED "; 00925 if (flags & BC_POUT_FLAGS_STRIDE_UV) res += "UVSTRIDE "; 00926 if (flags & BC_POUT_FLAGS_MODE) res += "APPMODE "; 00927 if (flags & BC_POUT_FLAGS_FMT_CHANGE) res += "FORMATCHANGED "; 00928 if (flags & BC_POUT_FLAGS_PIB_VALID) res += "PIBVALID "; 00929 if (flags & BC_POUT_FLAGS_ENCRYPTED) res += "ENCRYPTED "; 00930 if (flags & BC_POUT_FLAGS_FLD_BOT) res += "FIELDBOTTOM "; 00931 return res; 00932 } 00933 00934 PixelFormat bcmpixfmt_to_pixfmt(BC_OUTPUT_FORMAT fmt) 00935 { 00936 switch (fmt) 00937 { 00938 case OUTPUT_MODE420: return PIX_FMT_YUV420P; 00939 case OUTPUT_MODE422_YUY2: return PIX_FMT_YUYV422; 00940 case OUTPUT_MODE422_UYVY: return PIX_FMT_UYVY422; 00941 } 00942 return PIX_FMT_YUV420P; 00943 }
1.7.6.1