From 2f56dbbc3f3e90983ad8becf99bdf4f7192e07de Mon Sep 17 00:00:00 2001
From: Gavin Hurlbut <gjhurlbu@gmail.com>
Date: Wed, 28 Jul 2010 18:08:07 -0700
Subject: [PATCH] 6824-v5.patch from #6824
diff --git a/mythtv/libs/libmythtv/avformatdecoder.cpp b/mythtv/libs/libmythtv/avformatdecoder.cpp
index c7a526e..62e0a0a 100644
a
|
b
|
static int dts_decode_header(uint8_t *indata_ptr, int *rate, |
84 | 84 | int *nblks, int *sfreq); |
85 | 85 | static int encode_frame(bool dts, unsigned char* data, int len, |
86 | 86 | short *samples, int &samples_size); |
| 87 | static QSize get_video_dim(const AVCodecContext &ctx) |
| 88 | { |
| 89 | return QSize(ctx.width >> ctx.lowres, ctx.height >> ctx.lowres); |
| 90 | } |
| 91 | static float get_aspect(const AVCodecContext &ctx) |
| 92 | { |
| 93 | float aspect_ratio = 0.0f; |
| 94 | |
| 95 | if (ctx.sample_aspect_ratio.num && ctx.height) |
| 96 | { |
| 97 | aspect_ratio = av_q2d(ctx.sample_aspect_ratio) * (float) ctx.width; |
| 98 | aspect_ratio /= (float) ctx.height; |
| 99 | } |
| 100 | |
| 101 | if (aspect_ratio <= 0.0f || aspect_ratio > 6.0f) |
| 102 | { |
| 103 | if (ctx.height) |
| 104 | aspect_ratio = (float)ctx.width / (float)ctx.height; |
| 105 | else |
| 106 | aspect_ratio = 4.0f / 3.0f; |
| 107 | } |
| 108 | |
| 109 | return aspect_ratio; |
| 110 | } |
87 | 111 | |
88 | 112 | int get_avf_buffer_xvmc(struct AVCodecContext *c, AVFrame *pic); |
89 | 113 | int get_avf_buffer(struct AVCodecContext *c, AVFrame *pic); |
… |
… |
AvFormatDecoder::AvFormatDecoder(MythPlayer *parent, |
216 | 240 | const ProgramInfo &pginfo, |
217 | 241 | bool use_null_videoout, |
218 | 242 | bool allow_private_decode, |
219 | | bool no_hardware_decode) |
| 243 | bool no_hardware_decode, |
| 244 | AVSpecialDecode special_decoding) |
220 | 245 | : DecoderBase(parent, pginfo), |
221 | 246 | private_dec(NULL), |
222 | 247 | is_db_ignored(gCoreContext->IsDatabaseIgnored()), |
… |
… |
AvFormatDecoder::AvFormatDecoder(MythPlayer *parent, |
236 | 261 | video_codec_id(kCodec_NONE), |
237 | 262 | no_hardware_decoders(no_hardware_decode), |
238 | 263 | allow_private_decoders(allow_private_decode), |
| 264 | special_decode(special_decoding), |
239 | 265 | maxkeyframedist(-1), |
240 | 266 | // Closed Caption & Teletext decoders |
241 | 267 | ccd608(new CC608Decoder(parent->GetCC608Reader())), |
… |
… |
AvFormatDecoder::AvFormatDecoder(MythPlayer *parent, |
277 | 303 | CC708Window::forceWhiteOnBlackText = true; |
278 | 304 | |
279 | 305 | no_dts_hack = false; |
| 306 | |
| 307 | int x = gCoreContext->GetNumSetting("CommFlagFast", 0); |
| 308 | VERBOSE(VB_IMPORTANT, "CommFlagFast: " << x); |
| 309 | if (x == 0) |
| 310 | special_decode = (AVSpecialDecode)0; |
| 311 | VERBOSE(VB_IMPORTANT, "special_decode: " << special_decode); |
280 | 312 | } |
281 | 313 | |
282 | 314 | AvFormatDecoder::~AvFormatDecoder() |
… |
… |
void AvFormatDecoder::InitVideoCodec(AVStream *stream, AVCodecContext *enc, |
1129 | 1161 | <<") type ("<<codec_type_string(enc->codec_type) |
1130 | 1162 | <<")."); |
1131 | 1163 | |
1132 | | float aspect_ratio = 0.0; |
1133 | | |
1134 | 1164 | if (ringBuffer && ringBuffer->isDVD()) |
1135 | 1165 | directrendering = false; |
1136 | 1166 | |
1137 | | if (selectedStream) |
1138 | | { |
1139 | | fps = normalized_fps(stream, enc); |
1140 | | |
1141 | | if (enc->sample_aspect_ratio.num) |
1142 | | aspect_ratio = av_q2d(enc->sample_aspect_ratio); |
1143 | | else if (stream->sample_aspect_ratio.num) |
1144 | | aspect_ratio = av_q2d(stream->sample_aspect_ratio); |
1145 | | else |
1146 | | aspect_ratio = 1.0f; |
1147 | | |
1148 | | if (aspect_ratio <= 0.0f || aspect_ratio > 6.0f) |
1149 | | aspect_ratio = 1.0f; |
1150 | | |
1151 | | aspect_ratio *= (float)enc->width / (float)enc->height; |
1152 | | |
1153 | | current_width = enc->width; |
1154 | | current_height = enc->height; |
1155 | | current_aspect = aspect_ratio; |
1156 | | } |
1157 | | |
1158 | 1167 | enc->opaque = (void *)this; |
1159 | 1168 | enc->get_buffer = get_avf_buffer; |
1160 | 1169 | enc->release_buffer = release_avf_buffer; |
… |
… |
void AvFormatDecoder::InitVideoCodec(AVStream *stream, AVCodecContext *enc, |
1216 | 1225 | .arg(codec_id_string(enc->codec_id))); |
1217 | 1226 | } |
1218 | 1227 | |
| 1228 | if (special_decode) |
| 1229 | { |
| 1230 | if (special_decode & kAVSpecialDecode_SingleThreaded) |
| 1231 | enc->thread_count = 1; |
| 1232 | |
| 1233 | enc->flags |= CODEC_FLAG2_FAST; |
| 1234 | |
| 1235 | if ((CODEC_ID_MPEG2VIDEO == codec->id) || |
| 1236 | (CODEC_ID_MPEG1VIDEO == codec->id)) |
| 1237 | { |
| 1238 | if (special_decode & kAVSpecialDecode_FewBlocks) |
| 1239 | { |
| 1240 | uint total_blocks = (enc->height+15) / 16; |
| 1241 | enc->skip_top = (total_blocks+3) / 4; |
| 1242 | enc->skip_bottom = (total_blocks+3) / 4; |
| 1243 | } |
| 1244 | |
| 1245 | if (special_decode & kAVSpecialDecode_LowRes) |
| 1246 | enc->lowres = 2; // 1 = 1/2 size, 2 = 1/4 size |
| 1247 | } |
| 1248 | else if (CODEC_ID_H264 == codec->id) |
| 1249 | { |
| 1250 | if (special_decode & kAVSpecialDecode_NoLoopFilter) |
| 1251 | { |
| 1252 | enc->flags &= ~CODEC_FLAG_LOOP_FILTER; |
| 1253 | enc->skip_loop_filter = AVDISCARD_ALL; |
| 1254 | } |
| 1255 | } |
| 1256 | |
| 1257 | if (special_decode & kAVSpecialDecode_NoDecode) |
| 1258 | { |
| 1259 | enc->skip_idct = AVDISCARD_ALL; |
| 1260 | } |
| 1261 | } |
| 1262 | |
1219 | 1263 | if (selectedStream) |
1220 | 1264 | { |
1221 | | uint width = enc->width; |
1222 | | uint height = enc->height; |
| 1265 | fps = normalized_fps(stream, enc); |
| 1266 | QSize dim = get_video_dim(*enc); |
| 1267 | int width = current_width = dim.width(); |
| 1268 | int height = current_height = dim.height(); |
| 1269 | float aspect = current_aspect = get_aspect(*enc); |
1223 | 1270 | |
1224 | | if (width == 0 && height == 0) |
| 1271 | if (!width || !height) |
1225 | 1272 | { |
1226 | 1273 | VERBOSE(VB_PLAYBACK, LOC + "InitVideoCodec " |
1227 | 1274 | "invalid dimensions, resetting decoder."); |
1228 | | width = 640; |
| 1275 | width = 640; |
1229 | 1276 | height = 480; |
1230 | | fps = 29.97; |
1231 | | aspect_ratio = 4.0 / 3; |
| 1277 | fps = 29.97f; |
| 1278 | aspect = 4.0f / 3.0f; |
1232 | 1279 | } |
1233 | 1280 | |
1234 | 1281 | GetPlayer()->SetVideoParams(width, height, fps, |
1235 | | keyframedist, aspect_ratio, kScan_Detect, |
| 1282 | keyframedist, aspect, kScan_Detect, |
1236 | 1283 | dvd_video_codec_changed); |
1237 | 1284 | if (LCD *lcd = LCD::Get()) |
1238 | 1285 | { |
… |
… |
int AvFormatDecoder::ScanStreams(bool novideo) |
1646 | 1693 | private_dec = NULL; |
1647 | 1694 | m_h264_parser->Reset(); |
1648 | 1695 | |
1649 | | uint width = max(enc->width, 16); |
1650 | | uint height = max(enc->height, 16); |
| 1696 | QSize dim = get_video_dim(*enc); |
| 1697 | uint width = max(dim.width(), 16); |
| 1698 | uint height = max(dim.height(), 16); |
1651 | 1699 | QString dec = "ffmpeg"; |
1652 | 1700 | uint thread_count = 1; |
1653 | 1701 | |
… |
… |
void AvFormatDecoder::MpegPreProcessPkt(AVStream *stream, AVPacket *pkt) |
2631 | 2679 | SequenceHeader *seq = reinterpret_cast<SequenceHeader*>( |
2632 | 2680 | const_cast<uint8_t*>(bufptr)); |
2633 | 2681 | |
2634 | | uint width = seq->width(); |
2635 | | uint height = seq->height(); |
| 2682 | uint width = seq->width() >> context->lowres; |
| 2683 | uint height = seq->height() >> context->lowres; |
2636 | 2684 | float aspect = seq->aspect(context->sub_id == 1); |
2637 | 2685 | float seqFPS = seq->fps(); |
2638 | 2686 | |
2639 | | bool changed = (seqFPS > fps+0.01) || (seqFPS < fps-0.01); |
| 2687 | bool changed = (seqFPS > fps+0.01f) || (seqFPS < fps-0.01f); |
2640 | 2688 | changed |= (width != (uint)current_width ); |
2641 | 2689 | changed |= (height != (uint)current_height); |
2642 | 2690 | changed |= fabs(aspect - current_aspect) > eps; |
… |
… |
void AvFormatDecoder::MpegPreProcessPkt(AVStream *stream, AVPacket *pkt) |
2661 | 2709 | |
2662 | 2710 | // fps debugging info |
2663 | 2711 | float avFPS = normalized_fps(stream, context); |
2664 | | if ((seqFPS > avFPS+0.01) || (seqFPS < avFPS-0.01)) |
| 2712 | if ((seqFPS > avFPS+0.01f) || (seqFPS < avFPS-0.01f)) |
2665 | 2713 | { |
2666 | 2714 | VERBOSE(VB_PLAYBACK, LOC + |
2667 | 2715 | QString("avFPS(%1) != seqFPS(%2)") |
… |
… |
bool AvFormatDecoder::H264PreProcessPkt(AVStream *stream, AVPacket *pkt) |
2735 | 2783 | continue; |
2736 | 2784 | } |
2737 | 2785 | |
2738 | | float aspect_ratio; |
2739 | | if (context->sample_aspect_ratio.num == 0) |
2740 | | aspect_ratio = 0.0f; |
2741 | | else |
2742 | | aspect_ratio = av_q2d(context->sample_aspect_ratio) * |
2743 | | context->width / context->height; |
2744 | | |
2745 | | if (aspect_ratio <= 0.0f || aspect_ratio > 6.0f) |
2746 | | aspect_ratio = (float)context->width / context->height; |
2747 | | |
2748 | | uint width = context->width; |
2749 | | uint height = context->height; |
| 2786 | float aspect_ratio = get_aspect(*context); |
| 2787 | QSize dim = get_video_dim(*context); |
| 2788 | uint width = dim.width(); |
| 2789 | uint height = dim.height(); |
2750 | 2790 | float seqFPS = normalized_fps(stream, context); |
2751 | 2791 | |
2752 | | bool changed = (seqFPS > fps+0.01) || (seqFPS < fps-0.01); |
| 2792 | bool changed = (seqFPS > fps+0.01f) || (seqFPS < fps-0.01f); |
2753 | 2793 | changed |= (width != (uint)current_width ); |
2754 | 2794 | changed |= (height != (uint)current_height); |
2755 | 2795 | changed |= fabs(aspect_ratio - current_aspect) > eps; |
… |
… |
bool AvFormatDecoder::H264PreProcessPkt(AVStream *stream, AVPacket *pkt) |
2771 | 2811 | |
2772 | 2812 | // fps debugging info |
2773 | 2813 | float avFPS = normalized_fps(stream, context); |
2774 | | if ((seqFPS > avFPS+0.01) || (seqFPS < avFPS-0.01)) |
| 2814 | if ((seqFPS > avFPS+0.01f) || (seqFPS < avFPS-0.01f)) |
2775 | 2815 | { |
2776 | 2816 | VERBOSE(VB_PLAYBACK, LOC + |
2777 | 2817 | QString("avFPS(%1) != seqFPS(%2)") |
… |
… |
bool AvFormatDecoder::ProcessVideoPacket(AVStream *curstream, AVPacket *pkt) |
2912 | 2952 | tmppicture.linesize[1] = picframe->pitches[1]; |
2913 | 2953 | tmppicture.linesize[2] = picframe->pitches[2]; |
2914 | 2954 | |
| 2955 | QSize dim = get_video_dim(*context); |
2915 | 2956 | sws_ctx = sws_getCachedContext(sws_ctx, context->width, |
2916 | 2957 | context->height, context->pix_fmt, |
2917 | 2958 | context->width, context->height, |
… |
… |
bool AvFormatDecoder::ProcessVideoPacket(AVStream *curstream, AVPacket *pkt) |
2922 | 2963 | VERBOSE(VB_IMPORTANT, LOC_ERR + "Failed to allocate sws context"); |
2923 | 2964 | return false; |
2924 | 2965 | } |
2925 | | sws_scale(sws_ctx, mpa_pic.data, mpa_pic.linesize, 0, context->height, |
| 2966 | sws_scale(sws_ctx, mpa_pic.data, mpa_pic.linesize, 0, dim.height(), |
2926 | 2967 | tmppicture.data, tmppicture.linesize); |
2927 | 2968 | |
2928 | 2969 | |
diff --git a/mythtv/libs/libmythtv/avformatdecoder.h b/mythtv/libs/libmythtv/avformatdecoder.h
index 23d990b..a82b30b 100644
a
|
b
|
|
2 | 2 | #define AVFORMATDECODER_H_ |
3 | 3 | |
4 | 4 | #include <QString> |
| 5 | #include <QMap> |
5 | 6 | #include <QList> |
6 | 7 | |
7 | 8 | #include "programinfo.h" |
… |
… |
class AvFormatDecoder : public DecoderBase |
81 | 82 | AvFormatDecoder(MythPlayer *parent, const ProgramInfo &pginfo, |
82 | 83 | bool use_null_video_out, |
83 | 84 | bool allow_private_decode = true, |
84 | | bool no_hardware_decode = false); |
| 85 | bool no_hardware_decode = false, |
| 86 | AVSpecialDecode av_special_decode = kAVSpecialDecode_None); |
85 | 87 | ~AvFormatDecoder(); |
86 | 88 | |
87 | 89 | void CloseCodecs(); |
… |
… |
class AvFormatDecoder : public DecoderBase |
267 | 269 | MythCodecID video_codec_id; |
268 | 270 | bool no_hardware_decoders; |
269 | 271 | bool allow_private_decoders; |
| 272 | AVSpecialDecode special_decode; |
270 | 273 | |
271 | 274 | int maxkeyframedist; |
272 | 275 | |
diff --git a/mythtv/libs/libmythtv/mythplayer.cpp b/mythtv/libs/libmythtv/mythplayer.cpp
index 9738516..f93be02 100644
a
|
b
|
int MythPlayer::OpenFile(uint retries, bool allow_libmpeg2) |
956 | 956 | (player_ctx->IsPBP() && !player_ctx->IsPrimaryPBP()); |
957 | 957 | SetDecoder(new AvFormatDecoder(this, *player_ctx->playingInfo, |
958 | 958 | using_null_videoout, |
959 | | allow_libmpeg2, noaccel)); |
| 959 | allow_libmpeg2, noaccel, |
| 960 | player_ctx->GetSpecialDecode())); |
960 | 961 | } |
961 | 962 | player_ctx->UnlockPlayingInfo(__FILE__, __LINE__); |
962 | 963 | if (GetDecoder()) |
diff --git a/mythtv/libs/libmythtv/playercontext.cpp b/mythtv/libs/libmythtv/playercontext.cpp
index fcd62ab..b6d3316 100644
a
|
b
|
void PlayerThread::run(void) |
37 | 37 | PlayerContext::PlayerContext(const QString &inUseID) : |
38 | 38 | recUsage(inUseID), player(NULL), playerUnsafe(false), recorder(NULL), |
39 | 39 | tvchain(NULL), buffer(NULL), playingInfo(NULL), |
40 | | playingLen(0), nohardwaredecoders(false), last_cardid(-1), last_framerate(30.0f), |
| 40 | playingLen(0), specialDecode(kAVSpecialDecode_None), |
| 41 | nohardwaredecoders(false), last_cardid(-1), last_framerate(30.0f), |
41 | 42 | // Fast forward state |
42 | 43 | ff_rew_state(0), ff_rew_index(0), ff_rew_speed(0), |
43 | 44 | // Other state |
diff --git a/mythtv/libs/libmythtv/playercontext.h b/mythtv/libs/libmythtv/playercontext.h
index 3e0e672..ae769bf 100644
a
|
b
|
class MPUBLIC PlayerContext |
119 | 119 | void SetPIPState(PIPState change) { pipState = change; } |
120 | 120 | void SetPlayerChangingBuffers(bool val) { playerUnsafe = val; } |
121 | 121 | void SetNoHardwareDecoders(void) { nohardwaredecoders = true; } |
| 122 | void SetSpecialDecode(AVSpecialDecode sp) { specialDecode = sp; } |
122 | 123 | |
123 | 124 | // Gets |
124 | 125 | QRect GetStandAlonePIPRect(void); |
… |
… |
class MPUBLIC PlayerContext |
131 | 132 | QString GetPlayMessage(void) const; |
132 | 133 | TVState GetState(void) const; |
133 | 134 | bool GetPlayingInfoMap(InfoMap &infoMap) const; |
| 135 | AVSpecialDecode GetSpecialDecode(void) const { return specialDecode; } |
134 | 136 | |
135 | 137 | // Boolean Gets |
136 | 138 | bool IsPIPSupported(void) const; |
… |
… |
class MPUBLIC PlayerContext |
169 | 171 | RingBuffer *buffer; |
170 | 172 | ProgramInfo *playingInfo; ///< Currently playing info |
171 | 173 | long long playingLen; ///< Initial CalculateLength() |
| 174 | AVSpecialDecode specialDecode; |
172 | 175 | bool nohardwaredecoders; // < Disable use of VDPAU decoding |
173 | 176 | int last_cardid; ///< CardID of current/last recorder |
174 | 177 | float last_framerate; ///< Estimated framerate from recorder |
diff --git a/mythtv/libs/libmythtv/videoouttypes.h b/mythtv/libs/libmythtv/videoouttypes.h
index 37b9517..b3401a3 100644
a
|
b
|
typedef enum VideoErrorState |
109 | 109 | kError_Switch_Renderer = 0x04, // Current renderer is not preferred choice |
110 | 110 | } VideoErrorState; |
111 | 111 | |
| 112 | typedef enum AVSpecialDecode |
| 113 | { |
| 114 | kAVSpecialDecode_None = 0x00, |
| 115 | kAVSpecialDecode_LowRes = 0x01, |
| 116 | kAVSpecialDecode_SingleThreaded = 0x02, |
| 117 | kAVSpecialDecode_FewBlocks = 0x04, |
| 118 | kAVSpecialDecode_NoLoopFilter = 0x08, |
| 119 | kAVSpecialDecode_NoDecode = 0x10, |
| 120 | } AVSpecialDecode; |
| 121 | |
112 | 122 | inline bool is_interlaced(FrameScanType scan) |
113 | 123 | { |
114 | 124 | return (kScan_Interlaced == scan) || (kScan_Intr2ndField == scan); |
diff --git a/mythtv/programs/mythcommflag/main.cpp b/mythtv/programs/mythcommflag/main.cpp
index 050ffc9..bf2bda7 100644
a
|
b
|
int BuildVideoMarkup(ProgramInfo *program_info, bool useDB) |
172 | 172 | |
173 | 173 | MythCommFlagPlayer *cfp = new MythCommFlagPlayer(); |
174 | 174 | PlayerContext *ctx = new PlayerContext("seektable rebuilder"); |
| 175 | ctx->SetSpecialDecode(kAVSpecialDecode_NoDecode); |
175 | 176 | ctx->SetPlayingInfo(program_info); |
176 | 177 | ctx->SetRingBuffer(tmprbuf); |
177 | 178 | ctx->SetPlayer(cfp); |
… |
… |
int FlagCommercials( |
756 | 757 | MythCommFlagPlayer *cfp = new MythCommFlagPlayer(); |
757 | 758 | |
758 | 759 | PlayerContext *ctx = new PlayerContext(kFlaggerInUseID); |
| 760 | |
| 761 | AVSpecialDecode sp = (AVSpecialDecode) |
| 762 | (kAVSpecialDecode_LowRes | |
| 763 | kAVSpecialDecode_SingleThreaded | |
| 764 | kAVSpecialDecode_NoLoopFilter); |
| 765 | |
| 766 | /* blank detector needs to be only sample center for this optimization. */ |
| 767 | if ((COMM_DETECT_BLANKS == commDetectMethod) || |
| 768 | (COMM_DETECT_2_BLANK == commDetectMethod)) |
| 769 | { |
| 770 | sp = (AVSpecialDecode) (sp | kAVSpecialDecode_FewBlocks); |
| 771 | } |
| 772 | |
| 773 | ctx->SetSpecialDecode(sp); |
| 774 | |
759 | 775 | ctx->SetPlayingInfo(program_info); |
760 | 776 | ctx->SetRingBuffer(tmprbuf); |
761 | 777 | ctx->SetPlayer(cfp); |
diff --git a/mythtv/programs/mythfrontend/globalsettings.cpp b/mythtv/programs/mythfrontend/globalsettings.cpp
index 5223f00..74d0a28 100644
a
|
b
|
static GlobalComboBox *CommercialSkipMethod() |
746 | 746 | return bc; |
747 | 747 | } |
748 | 748 | |
| 749 | static GlobalCheckBox *CommFlagFast() |
| 750 | { |
| 751 | GlobalCheckBox *gc = new GlobalCheckBox("CommFlagFast"); |
| 752 | gc->setLabel(QObject::tr("Enable experimental speedup of commercial detection")); |
| 753 | gc->setValue(false); |
| 754 | gc->setHelpText(QObject::tr("If enabled, experimental commercial detection " |
| 755 | "speedups will be enabled.")); |
| 756 | return gc; |
| 757 | } |
| 758 | |
749 | 759 | static HostComboBox *AutoCommercialSkip() |
750 | 760 | { |
751 | 761 | HostComboBox *gc = new HostComboBox("AutoCommercialSkip"); |
… |
… |
GeneralSettings::GeneralSettings() |
4309 | 4319 | VerticalConfigurationGroup* jobs = new VerticalConfigurationGroup(false); |
4310 | 4320 | jobs->setLabel(QObject::tr("General (Jobs)")); |
4311 | 4321 | jobs->addChild(CommercialSkipMethod()); |
| 4322 | jobs->addChild(CommFlagFast()); |
4312 | 4323 | jobs->addChild(AggressiveCommDetect()); |
4313 | 4324 | jobs->addChild(DefaultTranscoder()); |
4314 | 4325 | jobs->addChild(DeferAutoTranscodeDays()); |