- Timestamp:
- 05/22/08 16:45:06 (4 months ago)
- Files:
-
- branches/perian-1.1 (modified) (1 prop)
- branches/perian-1.1/CAPublicUtility/CAStreamBasicDescription.cpp (modified) (2 diffs)
- branches/perian-1.1/Codecprintf.c (modified) (3 diffs)
- branches/perian-1.1/Codecprintf.h (modified) (1 diff)
- branches/perian-1.1/ColorConversions.c (modified) (11 diffs)
- branches/perian-1.1/ColorConversions.h (modified) (1 diff)
- branches/perian-1.1/CommonUtils.c (modified) (1 diff)
- branches/perian-1.1/CommonUtils.h (modified) (1 diff)
- branches/perian-1.1/ECQTComponent.h (copied) (copied from trunk/ECQTComponent.h)
- branches/perian-1.1/ECQTComponent.m (copied) (copied from trunk/ECQTComponent.m)
- branches/perian-1.1/FFissionCodec/FFissionCodec.cpp (modified) (1 diff)
- branches/perian-1.1/FFusionCodec.c (modified) (42 diffs)
- branches/perian-1.1/FFusionCodec.h (modified) (2 diffs)
- branches/perian-1.1/FFusionCodec.r (modified) (9 diffs)
- branches/perian-1.1/MatroskaCodecIDs.cpp (modified) (12 diffs)
- branches/perian-1.1/MatroskaExportVersion.h (modified) (1 diff)
- branches/perian-1.1/MatroskaImport.h (modified) (1 diff)
- branches/perian-1.1/MatroskaImportPrivate.cpp (modified) (15 diffs)
- branches/perian-1.1/MatroskaImportVersion.h (modified) (1 diff)
- branches/perian-1.1/Patches (copied) (copied from trunk/Patches)
- branches/perian-1.1/Perian.xcodeproj/project.pbxproj (modified) (15 diffs)
- branches/perian-1.1/PerianPrefPane.nib/info.nib (modified) (1 diff)
- branches/perian-1.1/PerianPrefPane.nib/keyedobjects.nib (modified) (previous)
- branches/perian-1.1/Plists/Perian-Info.plist (modified) (2 diffs)
- branches/perian-1.1/Plists/PerianPane-Info.plist (modified) (1 diff)
- branches/perian-1.1/Plists/PerianUpdateChecker-Info.plist (modified) (1 diff)
- branches/perian-1.1/Release/Changes.txt (modified) (1 diff)
- branches/perian-1.1/Release/Makefile (modified) (2 diffs)
- branches/perian-1.1/Release/Read Me.rtf (modified) (3 diffs)
- branches/perian-1.1/Subtitles/SubATSUIRenderer.h (modified) (2 diffs)
- branches/perian-1.1/Subtitles/SubATSUIRenderer.m (modified) (20 diffs)
- branches/perian-1.1/Subtitles/SubContext.h (modified) (2 diffs)
- branches/perian-1.1/Subtitles/SubContext.m (modified) (1 diff)
- branches/perian-1.1/Subtitles/SubImport.h (modified) (2 diffs)
- branches/perian-1.1/Subtitles/SubImport.mm (modified) (9 diffs)
- branches/perian-1.1/Subtitles/SubParsing.h (modified) (1 diff)
- branches/perian-1.1/Subtitles/SubParsing.m.rl (modified) (5 diffs)
- branches/perian-1.1/Subtitles/SubUtilities.m (modified) (1 diff)
- branches/perian-1.1/Subtitles/latin-detector.c (added)
- branches/perian-1.1/Subtitles/ssa2html.m (added)
- branches/perian-1.1/TextSubCodec.c (modified) (1 diff)
- branches/perian-1.1/TextSubCodec.h (modified) (1 diff)
- branches/perian-1.1/UniversalDetector/universalchardet/src/nsMBCSSM.cpp (modified) (4 diffs)
- branches/perian-1.1/Update Checker Sources/main.m (modified) (1 diff)
- branches/perian-1.1/VobSubCodec.c (modified) (1 diff)
- branches/perian-1.1/VobSubCodec.h (modified) (1 diff)
- branches/perian-1.1/bitstream_info.c (modified) (9 diffs)
- branches/perian-1.1/config.h (added)
- branches/perian-1.1/createStaticLibs.sh (modified) (6 diffs)
- branches/perian-1.1/ff_MovieImport.c (modified) (3 diffs)
- branches/perian-1.1/ff_MovieImportVersion.h (modified) (1 diff)
- branches/perian-1.1/ff_private.c (modified) (8 diffs)
- branches/perian-1.1/ff_private.h (modified) (1 diff)
- branches/perian-1.1/ffmpeg-patch (deleted)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
branches/perian-1.1
- Property svn:externals changed from
ffmpeg -r11099 svn://svn.mplayerhq.hu/ffmpeg/trunk
libebml -r1297 http://svn.matroska.org/svn/matroska/trunk/libebml
libmatroska -r1297 http://svn.matroska.org/svn/matroska/trunk/libmatroska
a52codec -r61 http://svn.cod3r.com/a52codec/trunk
to
ffmpeg -r 13239 svn://svn.mplayerhq.hu/ffmpeg/trunk
libebml -r 1306 https://services.corecodec.com/svn/matroska/trunk/libebml
libmatroska -r 1306 https://services.corecodec.com/svn/matroska/trunk/libmatroska
a52codec -r 64 http://svn.cod3r.com/a52codec/trunk
- Property svn:externals changed from
branches/perian-1.1/CAPublicUtility/CAStreamBasicDescription.cpp
r741 r887 50 50 #include <Endian.h> 51 51 #endif 52 53 #import "CodecIDs.h"54 52 55 53 const AudioStreamBasicDescription CAStreamBasicDescription::sEmpty = { 0.0, 0, 0, 0, 0, 0, 0, 0, 0 }; … … 274 272 275 273 case kAudioFormatAC3: 276 case kAudioFormatAC3MS:277 274 strcpy(outName, "AC-3"); 278 275 break; branches/perian-1.1/Codecprintf.c
r332 r887 15 15 #ifdef DEBUG_BUILD 16 16 #define CODEC_HEADER "Perian Codec: " 17 #define FILELOG 17 18 18 19 static int Codecvprintf(FILE *fileLog, const char *format, va_list va, int print_header) … … 24 25 { 25 26 if(print_header) 26 fprintf( glob->fileLog, CODEC_HEADER);27 fprintf(fileLog, CODEC_HEADER); 27 28 ret = vfprintf(fileLog, format, va); 28 fflush( glob->fileLog);29 fflush(fileLog); 29 30 } 30 31 else … … 47 48 va_list va; 48 49 va_start(va, format); 49 ret = Codecvprintf(fileLog, format, va, 1);50 ret = Codecvprintf(fileLog, format, va, !fileLog); 50 51 va_end(va); 51 52 return ret; 52 53 } 53 54 54 void FourCCprintf (char *string, unsigned long a)55 const char *FourCCString(FourCharCode c) 55 56 { 56 if (a < 64) 57 { 58 Codecprintf(NULL, "%s%ld\n", string, a); 59 } 60 else 61 { 62 Codecprintf(NULL, "%s%c%c%c%c\n", string, 63 (unsigned char)((a >> 24) & 0xff), 64 (unsigned char)((a >> 16) & 0xff), 65 (unsigned char)((a >> 8) & 0xff), 66 (unsigned char)(a & 0xff)); 67 } 57 static unsigned char fourcc[5] = {0}; 58 int i; 59 60 for (i = 0; i < 4; i++) fourcc[i] = c >> 8*(3-i); 61 62 return (char*)fourcc; 68 63 } 64 65 void FourCCprintf (char *string, FourCharCode a) 66 { 67 Codecprintf(NULL, "%s%s\n", string, FourCCString(a)); 68 } 69 69 70 #else 70 71 #define Codecvprintf(file, fmt, va, print_header) /**/ branches/perian-1.1/Codecprintf.h
r214 r887 14 14 #ifdef DEBUG_BUILD 15 15 int Codecprintf(FILE *, const char *format, ...); 16 void FourCCprintf(char *string, unsigned long a); 16 void FourCCprintf(char *string, FourCharCode a); 17 const char *FourCCString(FourCharCode c); 17 18 #else 18 19 #define Codecprintf(file, fmt, ...) /**/ branches/perian-1.1/ColorConversions.c
r629 r887 24 24 #include <sys/sysctl.h> 25 25 26 #ifndef GOOD_COMPILER 27 #define noinline __attribute__((noinline)) 28 #else 29 #define noinline 30 #endif 31 32 #define unlikely(x) __builtin_expect(x, 0) 33 26 34 //----------------------------------------------------------------- 27 35 // FastY420 … … 58 66 // have a decent OS/QT version. 59 67 //----------------------------------------------------------------- 68 69 static void noinline Y420toY422_lastrow(UInt8 *o, const UInt8 *yc, const UInt8 *uc, const UInt8 *vc, unsigned halfWidth) 70 { 71 unsigned x; 72 for(x=0; x < halfWidth; x++) 73 { 74 unsigned x4 = x*4, x2 = x*2; 75 o[x4] = uc[x]; 76 o[x4+1] = yc[x2]; 77 o[x4+2] = vc[x]; 78 o[x4+3] = yc[x2+1]; 79 } 80 } 81 82 #define HandleLastRow(o, yc, uc, vc, halfWidth, height) if (unlikely(height & 1)) Y420toY422_lastrow(o, yc, uc, vc, halfWidth) 60 83 61 84 #ifdef __BIG_ENDIAN__ … … 104 127 baseAddr += outRB * 2; 105 128 } 129 130 HandleLastRow(baseAddr, inY, inU, inV, halfWidth, height); 106 131 } 107 132 … … 154 179 vc += rV; 155 180 } 181 182 HandleLastRow(o, yc, uc, vc, width / 2, height); 156 183 } 157 184 … … 186 213 __m128i * uv = (__m128i*)uc,* vv = (__m128i*)vc; 187 214 215 #if 0 216 asm volatile( 217 "\n0: \n\t" 218 "movdqa (%2), %%xmm0 \n\t" 219 "movdqa 16(%2), %%xmm2 \n\t" 220 "movdqa (%3), %%xmm1 \n\t" 221 "movdqa 16(%3), %%xmm3 \n\t" 222 "movdqu (%4), %%xmm4 \n\t" 223 "movdqu (%5), %%xmm5 \n\t" 224 "addl $32, %2 \n\t" 225 "addl $32, %3 \n\t" 226 "addl $16, %4 \n\t" 227 "addl $16, %5 \n\t" 228 "movdqa %%xmm4, %%xmm6 \n\t" 229 "punpcklbw %%xmm5, %%xmm4 \n\t" /*chroma_l*/ 230 "punpckhbw %%xmm5, %%xmm6 \n\t" /*chroma_h*/ 231 "movdqa %%xmm4, %%xmm5 \n\t" 232 "punpcklbw %%xmm0, %%xmm5 \n\t" 233 "movntdq %%xmm5, (%0) \n\t" /*ov[x4]*/ 234 "movdqa %%xmm4, %%xmm5 \n\t" 235 "punpckhbw %%xmm0, %%xmm5 \n\t" 236 "movntdq %%xmm5, 16(%0) \n\t" /*ov[x4+1]*/ 237 "movdqa %%xmm6, %%xmm5 \n\t" 238 "punpcklbw %%xmm2, %%xmm5 \n\t" 239 "movntdq %%xmm5, 32(%0) \n\t" /*ov[x4+2]*/ 240 "movdqa %%xmm6, %%xmm5 \n\t" 241 "punpckhbw %%xmm2, %%xmm5 \n\t" 242 "movntdq %%xmm5, 48(%0) \n\t" /*ov[x4+3]*/ 243 "addl $64, %0 \n\t" 244 "movdqa %%xmm4, %%xmm5 \n\t" 245 "punpcklbw %%xmm1, %%xmm5 \n\t" 246 "movntdq %%xmm5, (%1) \n\t" /*ov2[x4]*/ 247 "punpckhbw %%xmm1, %%xmm4 \n\t" 248 "movntdq %%xmm4, 16(%1) \n\t" /*ov2[x4+1]*/ 249 "movdqa %%xmm6, %%xmm5 \n\t" 250 "punpcklbw %%xmm3, %%xmm5 \n\t" 251 "movntdq %%xmm5, 32(%1) \n\t" /*ov2[x4+2]*/ 252 "punpckhbw %%xmm3, %%xmm6 \n\t" 253 "movntdq %%xmm6, 48(%1) \n\t" /*ov2[x4+3]*/ 254 "addl $64, %1 \n\t" 255 "dec %6 \n\t" 256 "jnz 0b \n\t" 257 : "+r" (ov), "+r" (ov2), 258 "+r" (yv), "+r" (yv2), "+r" (uv), "+r" (vv) 259 : "r" (vWidth) 260 ); 261 #else 188 262 for (x = 0; x < vWidth; x++) { 189 263 unsigned x2 = x*2, x4 = x*4; … … 205 279 _mm_stream_si128(&ov2[x4+3],_mm_unpackhi_epi8(chroma_h, tmp_y4)); 206 280 } 207 208 for (x = x * 16; x < halfwidth; x++) { 281 #endif 282 283 for (x=vWidth * 16; x < halfwidth; x++) { 209 284 unsigned x4 = x*4, x2 = x*2; 210 285 o2[x4] = o[x4] = uc[x]; … … 221 296 vc += rV; 222 297 } 223 } 224 225 226 static void __attribute__((noinline)) Y420toY422_x86_scalar(UInt8 * o, unsigned outRB, unsigned width, unsigned height, AVFrame * picture) 298 299 _mm_sfence(); 300 301 HandleLastRow(o, yc, uc, vc, halfwidth, height); 302 } 303 304 305 static void noinline Y420toY422_x86_scalar(UInt8 * o, unsigned outRB, unsigned width, unsigned height, AVFrame * picture) 227 306 { 228 307 UInt8 *yc = picture->data[0], *u = picture->data[1], *v = picture->data[2]; … … 248 327 v += rV; 249 328 } 329 330 HandleLastRow(o, yc, u, v, halfwidth, height); 250 331 } 251 332 … … 255 336 256 337 //make sure the ffmpeg picture buffers are aligned enough, they're only guaranteed to be 8-byte for some reason... 257 if ((yc | picture->linesize[0]) % 16 == 0) { 258 Y420toY422_sse2(o, outRB, width, height, picture); 259 _mm_sfence(); 260 } else Y420toY422_x86_scalar(o, outRB, width, height, picture); 338 if (!unlikely((yc | picture->linesize[0]) % 16)) Y420toY422_sse2(o, outRB, width, height, picture); 339 else Y420toY422_x86_scalar(o, outRB, width, height, picture); 261 340 } 262 341 #endif 342 343 void YA420toV408(UInt8* o, unsigned outRB, unsigned width, unsigned height, AVFrame * picture) 344 { 345 UInt8 *yc = picture->data[0], *u = picture->data[1], *v = picture->data[2], *a = picture->data[3]; 346 unsigned rY = picture->linesize[0], rU = picture->linesize[1], rV = picture->linesize[2], rA = picture->linesize[3], y, x; 347 348 for (y = 0; y < height; y++) { 349 for (x = 0; x < width; x++) { 350 o[x*4] = u[x/2]; 351 o[x*4+1] = yc[x]; 352 o[x*4+2] = v[x/2]; 353 o[x*4+3] = a[x]; 354 } 355 356 o += outRB; 357 yc += rY; 358 a += rA; 359 if (y & 1) { 360 u += rU; 361 v += rV; 362 } 363 } 364 } 263 365 264 366 void BGR24toRGB24(UInt8 *baseAddr, unsigned rowBytes, unsigned width, unsigned height, AVFrame *picture) … … 266 368 unsigned i, j; 267 369 UInt8 *srcPtr = picture->data[0]; 268 unsigned width_third = width / 3;269 370 270 371 for (i = 0; i < height; ++i) 271 372 { 272 for (j = 0; j < width _third; j ++)373 for (j = 0; j < width; j ++) 273 374 { 274 375 unsigned j3 = j * 3; … … 301 402 } 302 403 404 void RGB24toRGB24(UInt8 *baseAddr, unsigned rowBytes, unsigned width, unsigned height, AVFrame *picture) 405 { 406 unsigned y; 407 UInt8 *srcPtr = picture->data[0]; 408 409 for (y = 0; y < height; y++) { 410 memcpy(baseAddr, srcPtr, width * 3); 411 412 baseAddr += rowBytes; 413 srcPtr += picture->linesize[0]; 414 } 415 } 416 303 417 void Y422toY422(UInt8* o, unsigned outRB, unsigned width, unsigned height, AVFrame * picture) 304 418 { branches/perian-1.1/ColorConversions.h
r344 r887 23 23 extern void FastY420(UInt8 *baseAddr, AVFrame *picture); 24 24 extern void Y420toY422(UInt8* baseAddr, unsigned rowBytes, unsigned width, unsigned height, AVFrame * picture); 25 extern void YA420toV408(UInt8* o, unsigned outRB, unsigned width, unsigned height, AVFrame * picture); 25 26 extern void RGB32toRGB32(UInt8 *baseAddr, unsigned rowBytes, unsigned width, unsigned height, AVFrame *picture); 27 extern void RGB24toRGB24(UInt8 *baseAddr, unsigned rowBytes, unsigned width, unsigned height, AVFrame *picture); 26 28 extern void BGR24toRGB24(UInt8 *baseAddr, unsigned rowBytes, unsigned width, unsigned height, AVFrame *picture); 27 29 extern void Y422toY422(UInt8* o, unsigned outRB, unsigned width, unsigned height, AVFrame * picture); branches/perian-1.1/CommonUtils.c
r761 r887 286 286 return 0; 287 287 } 288 289 int IsFrameDroppingEnabled() 290 { 291 static int enabled = -1; 292 293 if (enabled == -1) enabled = getenv("PerianNoFrameDropping") == NULL; 294 295 return enabled; 296 } branches/perian-1.1/CommonUtils.h
r585 r887 39 39 int isImageDescriptionExtensionPresent(ImageDescriptionHandle desc, long type); 40 40 41 int IsFrameDroppingEnabled(); 42 41 43 #ifdef __cplusplus 42 44 } branches/perian-1.1/FFissionCodec/FFissionCodec.cpp
r525 r887 25 25 #include "FFissionCodec.h" 26 26 27 extern "C" void init Lib();27 extern "C" void init_FFmpeg(); 28 28 29 29 FFissionCodec::FFissionCodec(UInt32 inInputBufferByteSize) : ACSimpleCodec(inInputBufferByteSize) 30 30 { 31 init Lib();31 init_FFmpeg(); 32 32 33 33 avContext = avcodec_alloc_context(); branches/perian-1.1/FFusionCodec.c
r805 r887 62 62 bool used; 63 63 long frameNumber; 64 AVFrame returnedFrame; 64 65 } FFusionBuffer; 65 66 … … 89 90 long lastFrame; 90 91 FFusionBuffer *futureBuffer; 92 }; 93 94 struct per_frame_decode_stats 95 { 96 unsigned begin_calls; 97 unsigned decode_calls; 98 unsigned draw_calls; 99 unsigned end_calls; 100 }; 101 102 struct decode_stats 103 { 104 struct per_frame_decode_stats type[4]; 105 int max_frames_begun; 106 int max_frames_decoded; 91 107 }; 92 108 … … 108 124 int lastAllocatedBuffer; // the index of the buffer which was last allocated 109 125 // by the codec (and is the latest in decode order) 126 int shouldUseReturnedFrame; 110 127 struct begin_glob begin; 111 128 FFusionData data; 112 129 struct decode_glob decode; 130 struct decode_stats stats; 113 131 } FFusionGlobalsRecord, *FFusionGlobals; 114 132 … … 132 150 //--------------------------------------------------------------------------- 133 151 134 static OSErr FFusionDecompress( AVCodecContext *context, UInt8 *dataPtr, ICMDataProcRecordPtr dataProc, long width, long height, AVFrame *picture, long length);152 static OSErr FFusionDecompress(FFusionGlobals glob, AVCodecContext *context, UInt8 *dataPtr, ICMDataProcRecordPtr dataProc, long width, long height, AVFrame *picture, long length); 135 153 static int FFusionGetBuffer(AVCodecContext *s, AVFrame *pic); 136 154 static void FFusionReleaseBuffer(AVCodecContext *s, AVFrame *pic); … … 143 161 void ChangeHintText(int value, ControlRef staticTextField); 144 162 145 extern void init Lib();163 extern void init_FFmpeg(); 146 164 extern CFMutableStringRef GetHomeDirectory(); 165 166 #define FFusionDebugPrint(x...) if (glob->fileLog) Codecprintf(glob->fileLog, x); 167 #define not(x) ((x) ? "" : "not ") 147 168 148 169 //--------------------------------------------------------------------------- … … 165 186 #include <QuickTime/ComponentDispatchHelper.c> 166 187 167 void *launchUpdateChecker(void *args)188 static void *launchUpdateChecker(void *args) 168 189 { 169 190 FSRef *ref = (FSRef *)args; … … 209 230 } 210 231 232 static void RecomputeMaxCounts(FFusionGlobals glob) 233 { 234 int i; 235 unsigned begun = 0, decoded = 0, ended = 0, drawn = 0; 236 237 for (i = 0; i < 4; i++) { 238 struct per_frame_decode_stats *f = &glob->stats.type[i]; 239 240 begun += f->begin_calls; 241 decoded += f->decode_calls; 242 drawn += f->draw_calls; 243 ended += f->end_calls; 244 } 245 246 signed begin_diff = begun - ended, decode_diff = decoded - drawn; 247 248 if (abs(begin_diff) > glob->stats.max_frames_begun) glob->stats.max_frames_begun = begin_diff; 249 if (abs(decode_diff) > glob->stats.max_frames_decoded) glob->stats.max_frames_decoded = decode_diff; 250 } 251 252 static void DumpFrameDropStats(FFusionGlobals glob) 253 { 254 static const char types[4] = {'?', 'I', 'P', 'B'}; 255 int i; 256 257 if (!glob->fileLog || glob->decode.lastFrame == 0) return; 258 259 Codecprintf(glob->fileLog, "Type\t| BeginBand\t| DecodeBand\t| DrawBand\t| dropped before decode\t| dropped before draw\n"); 260 261 for (i = 0; i < 4; i++) { 262 struct per_frame_decode_stats *f = &glob->stats.type[i]; 263 264 Codecprintf(glob->fileLog, "%c\t| %d\t\t| %d\t\t| %d\t\t| %d/%f%%\t\t| %d/%f%%\n", types[i], f->begin_calls, f->decode_calls, f->draw_calls, 265 f->begin_calls - f->decode_calls,(f->begin_calls > f->decode_calls) ? ((float)(f->begin_calls - f->decode_calls)/(float)f->begin_calls) * 100. : 0., 266 f->decode_calls - f->draw_calls,(f->decode_calls > f->draw_calls) ? ((float)(f->decode_calls - f->draw_calls)/(float)f->decode_calls) * 100. : 0.); 267 } 268 } 269 211 270 //--------------------------------------------------------------------------- 212 271 // Component Routines … … 241 300 242 301 // FourCCprintf("Opening component for type ", descout.componentSubType); 243 244 302 // Allocate memory for our globals, set them up and inform the component manager that we've done so 245 303 … … 264 322 glob->data.frames = NULL; 265 323 glob->begin.parser = NULL; 266 #ifdef FILELOG 267 glob->fileLog = fopen("/tmp/perian.log", "a"); 268 #else 269 glob->fileLog = NULL; 270 #endif 324 if (getenv("PerianDebugLogging")) glob->fileLog = fopen("/tmp/perian.log", "a"); 325 else glob->fileLog = NULL; 326 glob->shouldUseReturnedFrame = 0; 271 327 272 328 // c = FindNextComponent(c, &cd); … … 306 362 } 307 363 364 FFusionDebugPrint("%p opened for '%s'\n", glob, FourCCString(glob->componentType)); 308 365 return err; 309 366 } … … 315 372 pascal ComponentResult FFusionCodecClose(FFusionGlobals glob, ComponentInstance self) 316 373 { 374 FFusionDebugPrint("%p closed.\n", glob); 375 DumpFrameDropStats(glob); 376 317 377 // Make sure to close the base component and deallocate our storage 318 319 378 if (glob) 320 379 { … … 417 476 pascal ComponentResult FFusionCodecInitialize(FFusionGlobals glob, ImageSubCodecDecompressCapabilities *cap) 418 477 { 478 Boolean doExperimentalFlags = getenv("PerianExperimentalQTFlags") != NULL; 419 479 420 480 // Secifies the size of the ImageSubCodecDecompressRecord structure … … 433 493 cap->subCodecSupportsOutOfOrderDisplayTimes = true; 434 494 cap->baseCodecShouldCallDecodeBandForAllFrames = true; 435 cap->subCodecSupportsScheduledBackwardsPlaybackWithDifferenceFrames = true; 436 437 // XXX enabling this seems to cause rare visible artifacts in h.264? 438 // cap->subCodecSupportsDrawInDecodeOrder = true; 495 cap->subCodecSupportsScheduledBackwardsPlaybackWithDifferenceFrames = !doExperimentalFlags; 496 cap->subCodecSupportsDrawInDecodeOrder = doExperimentalFlags; 439 497 cap->subCodecSupportsDecodeSmoothing = true; 440 498 } … … 468 526 // to the fourCC if it has not been done before 469 527 528 FFusionDebugPrint("%p Preflight called.\n", glob); 529 470 530 if (!glob->avCodec) 471 531 { 472 532 enum CodecID codecID = CODEC_ID_MPEG4; 473 533 474 init Lib();534 init_FFmpeg(); 475 535 initFFusionParsers(); 476 536 … … 577 637 case 'VP30': 578 638 case 'VP31': 639 glob->shouldUseReturnedFrame = TRUE; 579 640 codecID = CODEC_ID_VP3; 580 641 break; … … 612 673 codecID = CODEC_ID_NUV; 613 674 break; 614 675 case 'tscc': 676 codecID = CODEC_ID_TSCC; 677 break; 678 679 case 'ZMBV': 680 codecID = CODEC_ID_ZMBV; 681 break; 682 683 case 'VP6A': 684 codecID = CODEC_ID_VP6A; 685 break; 615 686 616 687 default: … … 622 693 glob->begin.parser = ffusionParserInit(codecID); 623 694 695 if ((codecID == CODEC_ID_MPEG4 || codecID == CODEC_ID_H264) && !glob->begin.parser) 696 Codecprintf(glob->fileLog, "This is a parseable format, but we couldn't open a parser!\n"); 697 624 698 // we do the same for the AVCodecContext since all context values are 625 699 // correctly initialized when calling the alloc function … … 634 708 glob->avContext->width = (**p->imageDescription).width; 635 709 glob->avContext->height = (**p->imageDescription).height; 710 glob->avContext->bits_per_sample = (**p->imageDescription).depth; 636 711 637 712 // We also pass the FourCC since it allows the H263 hybrid decoder … … 686 761 } 687 762 763 FFusionDebugPrint("%p preflighted for %dx%d '%s'. (%d bytes of extradata)\n", glob, (**p->imageDescription).width, (**p->imageDescription).height, FourCCString(glob->componentType), glob->avContext->extradata_size); 764 688 765 if(glob->avContext->extradata_size != 0 && glob->begin.parser != NULL) 689 766 ffusionParseExtraData(glob->begin.parser, glob->avContext->extradata, glob->avContext->extradata_size); … … 757 834 case PIX_FMT_RGB32: 758 835 pos[index++] = k32ARGBPixelFormat; 836 break; 837 case PIX_FMT_RGB24: 838 pos[index++] = k24RGBPixelFormat; 839 break; 840 case PIX_FMT_YUVA420P: 841 pos[index++] = k4444YpCbCrA8PixelFormat; 759 842 break; 760 843 case PIX_FMT_YUV420P: … … 786 869 capabilities->flags |= codecCanAsync | codecCanAsyncWhen; 787 870 871 FFusionDebugPrint("%p Preflight requesting colorspace '%s'. (error %d)\n", glob, FourCCString(pos[0]), err); 872 788 873 return err; 789 874 } … … 796 881 return kCodecFrameTypeKey; 797 882 } 798 else if(skippable )883 else if(skippable && IsFrameDroppingEnabled()) 799 884 return kCodecFrameTypeDroppableDifference; 800 885 else if(fftype != 0) … … 822 907 FFusionDecompressRecord *myDrp = (FFusionDecompressRecord *)drp->userDecompressRecord; 823 908 int redisplayFirstFrame = 0; 909 int type = 0; 910 int skippable = 0; 824 911 825 912 ////// … … 847 934 myDrp->frameData = NULL; 848 935 myDrp->buffer = NULL; 936 937 FFusionDebugPrint("%p BeginBand #%d. (%sdecoded, packed %d)\n", glob, p->frameNumber, not(myDrp->decoded), glob->packedType); 849 938 850 939 if (!glob->avContext) { … … 897 986 { 898 987 int parsedBufSize; 899 int type = 0;900 int skippable = 0;901 988 uint8_t *buffer = (uint8_t *)drp->codecData; 902 989 int bufferSize = p->bufferSize; … … 921 1008 else 922 1009 { 923 Codecprintf( NULL, "parse failed frame %d with size %d\n", p->frameNumber, bufferSize);1010 Codecprintf(glob->fileLog, "parse failed frame %d with size %d\n", p->frameNumber, bufferSize); 924 1011 if(glob->data.unparsedFrames.dataSize != 0) 925 Codecprintf( NULL, ", parser had extra data\n");1012 Codecprintf(glob->fileLog, ", parser had extra data\n"); 926 1013 } 927 1014 } … … 1012 1099 myDrp->frameNumber = p->frameNumber; 1013 1100 myDrp->GOPStartFrameNumber = glob->begin.lastIFrame; 1101 1102 glob->stats.type[drp->frameType].begin_calls++; 1103 RecomputeMaxCounts(glob); 1104 FFusionDebugPrint("%p BeginBand: frame #%d type %d. (%sskippable)\n", glob, myDrp->frameNumber, type, not(skippable)); 1105 1014 1106 return noErr; 1015 1107 } 1016 1108 1017 static OSErr PrereqDecompress(FrameData *prereq, AVCodecContext *context, ICMDataProcRecordPtr dataProc, long width, long height, AVFrame *picture) 1018 { 1109 static OSErr PrereqDecompress(FFusionGlobals glob, FrameData *prereq, AVCodecContext *context, ICMDataProcRecordPtr dataProc, long width, long height, AVFrame *picture) 1110 { 1111 FFusionDebugPrint("%p prereq-decompressing frame #%d.\n", glob, prereq->frameNumber); 1112 1019 1113 FrameData *preprereq = FrameDataCheckPrereq(prereq); 1020 1114 if(preprereq) 1021 PrereqDecompress( preprereq, context, dataProc, width, height, picture);1115 PrereqDecompress(glob, preprereq, context, dataProc, width, height, picture); 1022 1116 1023 1117 unsigned char *dataPtr = (unsigned char *)prereq->buffer; 1024 1118 int dataSize = prereq->dataSize; 1025 1119 1026 OSErr err = FFusionDecompress( context, dataPtr, dataProc, width, height, picture, dataSize);1120 OSErr err = FFusionDecompress(glob, context, dataPtr, dataProc, width, height, picture, dataSize); 1027 1121 1028 1122 return err; … … 1035 1129 1036 1130 FFusionDecompressRecord *myDrp = (FFusionDecompressRecord *)drp->userDecompressRecord; 1131 1132 glob->stats.type[drp->frameType].decode_calls++; 1133 RecomputeMaxCounts(glob); 1134 FFusionDebugPrint("%p DecodeBand #%d qtType %d. (packed %d)\n", glob, myDrp->frameNumber, drp->frameType, glob->packedType); 1037 1135 1038 1136 avcodec_get_frame_defaults(&tempFrame); … … 1043 1141 { 1044 1142 /* Skipped some frames in here */ 1143 FFusionDebugPrint("%p - frames skipped.\n", glob); 1045 1144 if(drp->frameType == kCodecFrameTypeKey || myDrp->GOPStartFrameNumber > glob->decode.lastFrame || myDrp->frameNumber < glob->decode.lastFrame) 1046 1145 { 1047 1146 /* If this is a key frame or the P frame before us is after the last frame (skip ahead), or we are before the last decoded frame (skip back) * 1048 1147 * then we are in a whole new GOP */ 1148 FFusionDebugPrint("%p - in a new GOP.\n", glob); 1049 1149 avcodec_flush_buffers(glob->avContext); 1050 1150 } … … 1059 1159 if(nextFrame != NULL) 1060 1160 { 1061 FFusionDecompress(glob ->avContext, nextFrame->buffer, NULL, myDrp->width, myDrp->height, &tempFrame, nextFrame->dataSize);1161 FFusionDecompress(glob, glob->avContext, nextFrame->buffer, NULL, myDrp->width, myDrp->height, &tempFrame, nextFrame->dataSize); 1062 1162 if(tempFrame.data[0] != NULL) 1063 1163 { … … 1085 1185 if(prereq) 1086 1186 { 1087 err = PrereqDecompress( prereq, glob->avContext, NULL, myDrp->width, myDrp->height, &tempFrame);1187 err = PrereqDecompress(glob, prereq, glob->avContext, NULL, myDrp->width, myDrp->height, &tempFrame); 1088 1188 if(tempFrame.data[0] != NULL) 1089 1189 { … … 1106 1206 1107 1207 avcodec_get_frame_defaults(&tempFrame); 1108 err = FFusionDecompress(glob ->avContext, dataPtr, dataProc, myDrp->width, myDrp->height, &tempFrame, dataSize);1109 1208 err = FFusionDecompress(glob, glob->avContext, dataPtr, dataProc, myDrp->width, myDrp->height, &tempFrame, dataSize); 1209 1110 1210 if (glob->packedType == PACKED_QUICKTIME_KNOWS_ORDER) { 1111 1211 myDrp->buffer = &glob->buffers[glob->lastAllocatedBuffer]; 1112 1212 myDrp->buffer->frameNumber = myDrp->frameNumber; 1213 myDrp->buffer->returnedFrame = tempFrame; 1113 1214 myDrp->decoded = true; 1114 1215 return err; … … 1124 1225 glob->decode.lastFrame = myDrp->frameNumber; 1125 1226 myDrp->decoded = true; 1227 if (myDrp->buffer) myDrp->buffer->returnedFrame = tempFrame; 1126 1228 1127 1229 FFusionDataMarkRead(&(glob->data), frameData); 1230 1231 FFusionDebugPrint("%p DecodeBand decoded #%d.\n", glob, glob->decode.lastFrame); 1128 1232 1129 1233 return err; … … 1158 1262 int i, j; 1159 1263 1264 glob->stats.type[drp->frameType].draw_calls++; 1265 RecomputeMaxCounts(glob); 1266 FFusionDebugPrint("%p DrawBand #%d. (%sdecoded)\n", glob, myDrp->frameNumber, not(myDrp->decoded)); 1267 1160 1268 if(!myDrp->decoded) 1161 1269 err = FFusionCodecDecodeBand(glob, drp, 0); … … 1170 1278 if(!picture || picture->data[0] == 0) 1171 1279 { 1172 if(glob->lastDisplayedFrame.data[0] != NULL) 1280 if(glob->shouldUseReturnedFrame && myDrp->buffer->returnedFrame.data[0]) 1281 //Some decoders (vp3) keep their internal buffers in an unusable state 1282 picture = &myDrp->buffer->returnedFrame; 1283 else if(glob->lastDisplayedFrame.data[0] != NULL) 1173 1284 //Display last frame 1174 1285 picture = &(glob->lastDisplayedFrame); … … 1212 1323 RGB32toRGB32((UInt8 *)drp->baseAddr, drp->rowBytes, myDrp->width, myDrp->height, picture); 1213 1324 }
