5 #include <exec/types.h>
6 #include <exec/libraries.h>
7 #include <exec/execbase.h>
8 #include <exec/lists.h>
9 #include <graphics/gfxbase.h>
10 #include <scalos/scalos.h>
11 #include <scalos/scalosgfx.h>
12 #include <datatypes/pictureclass.h>
13 #include <scalos/scalospreviewplugin.h>
14 #include <cybergraphx/cybergraphics.h>
15 #include <utility/hooks.h>
24 #include <clib/alib_protos.h>
26 #include <proto/dos.h>
27 #include <proto/exec.h>
28 #include <proto/utility.h>
29 #include <proto/scalosgfx.h>
30 #include <proto/graphics.h>
31 #include <proto/intuition.h>
37 #include <libavcodec/avcodec.h>
38 #include <libavcodec/imgconvert.h>
44 //---------------------------------------------------------------------------------------
46 // set BYTEDUMP to 1 if you need to use ByteDump()
50 #define DUMP_ARGB_LINE(argbh, component, yy)
52 #define DUMP_ARGB_LINE(argbh, component, yy) \
55 const struct ARGB *argb = &(argbh)->argb_ImageData[(yy) * (argbh)->argb_Width]; \
56 KPrintF(__FILE__ "/%s/%ld: w=%ld h=%ld yy=%ld #component:\n", __FUNC__, __LINE__, \
57 (argbh)->argb_Width, (argbh)->argb_Height, yy); \
58 KPrintF(__FILE__ "/%s/%ld: ", __FUNC__, __LINE__); \
59 for (n = 0; n < (argbh)->argb_Width; n++, argb++) \
61 if (n > 0 && 0 == n % 16) \
62 KPrintF("\n" __FILE__ "/%s/%ld: ", __FUNC__, __LINE__); \
63 KPrintF("%02lx ", argb->component); \
69 //---------------------------------------------------------------------------------------
75 int avinf_VideoStream
;
76 AVFormatContext
*avinf_pFormatContext
;
77 AVCodecContext
*avinf_pCodecContext
;
78 AVCodec
*avinf_pVideoCodec
;
79 AVStream
*avinf_pVideoStream
;
80 AVFrame
*avinf_pFrame
; // Video frame in native format
81 AVFrame
*avinf_pRGBFrame
; // Converted Video frame in RGB format
82 UBYTE
*avinf_Buffer
; // Buffer for RGB image data
83 BOOL avinf_CodecOpened
; // Flag: av_codec_open() succeeded
93 //---------------------------------------------------------------------------------------
95 struct GfxBase
*GfxBase
;
96 T_UTILITYBASE UtilityBase
;
97 struct Library
*CyberGfxBase
;
98 struct DosLibrary
*DOSBase
;
99 struct IntuitionBase
*IntuitionBase
;
100 struct ScalosGfxBase
*ScalosGfxBase
;
103 struct Library
*NewlibBase
;
104 struct Interface
*INewlib
;
105 struct GraphicsIFace
*IGraphics
;
106 struct UtilityIFace
*IUtility
;
107 struct ExecIFace
*IExec
;
108 struct CyberGfxIFace
*ICyberGfx
;
109 struct DOSIFace
*IDOS
;
110 struct IntuitionIFace
*IIntuition
;
111 struct ScalosGfxIFace
*IScalosGfx
;
112 #endif /* __amigaos4__ */
114 /* won't compile for me when defined as constants - mazze */
115 #define FILMHOLE_WIDTH (12)
116 #define FILMHOLE_HEIGHT (10)
118 STRPTR VersTag
= LIB_VERSTRING
;
120 //---------------------------------------------------------------------------------------
122 static BOOL
GenerateRemappedThumbnail(struct ScaWindowTask
*wt
,
123 CONST_STRPTR iconName
,
124 struct AVInfo
*avInfo
, struct VideoFrame
*vFrame
,
125 ULONG quality
, ULONG SupportedColors
, ULONG ReservedColors
,
126 ULONG ScaledWidth
, ULONG ScaledHeight
,
127 struct Screen
*WBScreen
, struct ScalosPreviewResult
*PVResult
);
128 static BOOL
GenerateARGBThumbnail(struct ScaWindowTask
*wt
,
129 CONST_STRPTR iconName
,
130 struct AVInfo
*avInfo
, struct VideoFrame
*vFrame
,
132 ULONG ScaledWidth
, ULONG ScaledHeight
,
133 struct ScalosPreviewResult
*PVResult
);
134 static void CleanupAVInfo(struct AVInfo
*avInfo
);
135 static BOOL
InitializeVideo(struct AVInfo
*avInfo
);
136 static BOOL
ReadVideoFrame(struct AVInfo
*avInfo
);
137 static BOOL
GetScaledVideoFrame(struct AVInfo
*avInfo
, int scaledSize
,
138 ULONG quality
, struct VideoFrame
*videoFrame
);
139 static BOOL
ConvertAndScaleFrame(struct AVInfo
*avInfo
, int format
, int scaledSize
,
140 int *scaledWidth
, int *scaledHeight
, ULONG quality
);
141 static void CalculateDimensions(int srcWidth
, int srcHeight
, int squareSize
, int *destWidth
, int *destHeight
);
142 static BOOL
AllocFrameData(AVFrame
**avFrame
, int width
, int height
, int format
);
143 static BOOL
VideoSeekFrame(struct AVInfo
*avInfo
, float timeInSeconds
);
144 static void OverlayFilmStrip(struct AVInfo
*avInfo
, struct VideoFrame
*videoFrame
);
145 static BOOL
IsInterestingFrame(const struct AVInfo
*avInfo
);
146 static BOOL
FindInterestingFrame(struct AVInfo
*avInfo
);
147 static void av_log_dummy_callback(void* ptr
, int level
, const char* fmt
, va_list vl
);
150 static void ByteDump(const unsigned char *Data
, size_t Length
);
151 #endif /* BYTEDUMP */
153 //-----------------------------------------------------------
155 BOOL
initPlugin(struct PluginBase
*PluginBase
)
159 d1(KPrintF("%s/%s/%ld: PluginBase=%08lx procName=<%s>\n", __FILE__
, __FUNC__
, __LINE__
, \
160 PluginBase
, FindTask(NULL
)->tc_Node
.ln_Name
));
164 if (_STI_240_InitMemFunctions())
166 #endif /* __amigaos4__ */
167 DOSBase
= (APTR
) OpenLibrary( "dos.library", 39 );
171 UtilityBase
= (T_UTILITYBASE
) OpenLibrary("utility.library", 39);
172 if (NULL
== UtilityBase
)
175 CyberGfxBase
= OpenLibrary(CYBERGFXNAME
, 0);
176 // CyberGfxBase may be NULL
178 IntuitionBase
= (struct IntuitionBase
*) OpenLibrary("intuition.library", 39);
179 d1(kprintf("%s/%s/%ld: IntuitionBase=%08lx\n", __FILE__
, __FUNC__
, __LINE__
, IntuitionBase
));
180 if (NULL
== IntuitionBase
)
183 GfxBase
= (struct GfxBase
*) OpenLibrary(GRAPHICSNAME
, 39);
184 d1(kprintf("%s/%s/%ld: GfxBase=%08lx\n", __FILE__
, __FUNC__
, __LINE__
, GfxBase
));
188 ScalosGfxBase
= (struct ScalosGfxBase
*) OpenLibrary(SCALOSGFXNAME
, 41);
189 d1(KPrintF("%s/%s/%ld: ScalosGfxBase=%08lx\n", __FILE__
, __FUNC__
, __LINE__
, ScalosGfxBase
));
190 if (NULL
== ScalosGfxBase
)
194 IDOS
= (struct DOSIFace
*) GetInterface((struct Library
*)DOSBase
, "main", 1, NULL
);
197 if (CyberGfxBase
!= NULL
) // CyberGfxBase may be NULL
199 ICyberGfx
= (struct CyberGfxIFace
*) GetInterface((struct Library
*) CyberGfxBase
, "main", 1, NULL
);
200 if (ICyberGfx
== NULL
)
203 IUtility
= (struct UtilityIFace
*) GetInterface((struct Library
*) UtilityBase
, "main", 1, NULL
);
204 if (NULL
== IUtility
)
206 IIntuition
= (struct IntuitionIFace
*) GetInterface((struct Library
*) IntuitionBase
, "main", 1, NULL
);
207 if (NULL
== IIntuition
)
209 IGraphics
= (struct GraphicsIFace
*) GetInterface((struct Library
*) GfxBase
, "main", 1, NULL
);
210 if (NULL
== IGraphics
)
212 IScalosGfx
= (struct ScalosGfxIFace
*) GetInterface((struct Library
*) ScalosGfxBase
, "main", 1, NULL
);
213 if (NULL
== IScalosGfx
)
215 NewlibBase
= OpenLibrary("newlib.library", 0);
216 if (NULL
== NewlibBase
)
218 INewlib
= GetInterface(NewlibBase
, "main", 1, NULL
);
221 #endif /* __amigaos4__ */
229 d1(KPrintF("%s/%s/%ld: Success\n", __FILE__
, __FUNC__
, __LINE__
));
236 void closePlugin(struct PluginBase
*PluginBase
)
238 d1(kprintf("%s/%s/%ld:\n", __FILE__
, __FUNC__
, __LINE__
));
243 _STD_240_TerminateMemFunctions();
249 DropInterface(INewlib
);
254 CloseLibrary(NewlibBase
);
259 DropInterface((struct Interface
*)ICyberGfx
);
264 DropInterface((struct Interface
*)IScalosGfx
);
269 DropInterface((struct Interface
*)IGraphics
);
274 DropInterface((struct Interface
*)IIntuition
);
279 DropInterface((struct Interface
*)IUtility
);
284 DropInterface((struct Interface
*)IDOS
);
287 #endif /* __amigaos4__ */
291 CloseLibrary(CyberGfxBase
);
294 if (NULL
!= ScalosGfxBase
)
296 CloseLibrary((struct Library
*) ScalosGfxBase
);
297 ScalosGfxBase
= NULL
;
301 CloseLibrary((struct Library
*) GfxBase
);
304 if (NULL
!= IntuitionBase
)
306 CloseLibrary((struct Library
*) IntuitionBase
);
307 IntuitionBase
= NULL
;
310 if (NULL
!= UtilityBase
)
312 CloseLibrary((struct Library
*) UtilityBase
);
317 CloseLibrary((struct Library
*) DOSBase
);
322 //--------------------------------------------------------------------------
324 LIBFUNC_P5(LONG
, LIBSCAPreviewGenerate
,
325 A0
, struct ScaWindowTask
*, wt
,
327 A2
, CONST_STRPTR
, iconName
,
328 A3
, struct TagItem
*, tagList
,
329 A6
, struct PluginBase
*, PluginBase
)
331 LONG Success
= FALSE
;
337 BPTR oldDir
= (BPTR
)NULL
;
338 struct AVInfo avInfo
;
339 struct VideoFrame vFrame
;
341 memset(&vFrame
, 0, sizeof(struct VideoFrame
));
343 d1(KPrintF("%s/%s/%ld: START iconName=<%s>\n", __FILE__
, __FUNC__
, __LINE__
, iconName
));
346 ULONG ThumbnailWidth
;
347 ULONG ThumbnailHeight
;
348 ULONG SupportedColors
;
350 struct Screen
*WBScreen
;
351 struct BitMapHeader
*bmhdExternal
;
352 struct ScalosPreviewResult
*PVResult
;
355 ULONG ReservedColors
;
358 memset(&avInfo
, 0, sizeof(struct AVInfo
));
360 av_log_set_callback(av_log_dummy_callback
);
362 d1(KPrintF("%s/%s/%ld: after av_log_set_callback\n", __FILE__
, __FUNC__
, __LINE__
));
364 PVResult
= (struct ScalosPreviewResult
*) GetTagData(SCALOSPREVIEW_ResultStruct
, (ULONG
)NULL
, tagList
);
365 if (NULL
== PVResult
)
369 memset(PVResult
, 0, sizeof(*PVResult
));
371 ThumbnailWidth
= GetTagData(SCALOSPREVIEW_ThumbnailWidth
, 0, tagList
);
372 if (0 == ThumbnailWidth
)
374 ThumbnailHeight
= GetTagData(SCALOSPREVIEW_ThumbnailHeight
, 0, tagList
);
375 if (0 == ThumbnailHeight
)
378 SupportedColors
= GetTagData(SCALOSPREVIEW_SupportedColors
, 0, tagList
);
379 if (SupportedColors
< 16)
382 ReservedColors
= GetTagData(SCALOSPREVIEW_ReservedColors
, 0, tagList
);
383 if (SupportedColors
< ReservedColors
+ 16)
386 bmhdExternal
= (struct BitMapHeader
*) GetTagData(SCALOSPREVIEW_ImgBitMapHeader
, (ULONG
)NULL
, tagList
);
387 quality
= GetTagData(SCALOSPREVIEW_Quality
, SCALOSPREVIEWA_Quality_Max
, tagList
);
389 WBScreen
= (struct Screen
*) GetTagData(SCALOSPREVIEW_Screen
, (ULONG
)NULL
, tagList
);
390 if (NULL
== WBScreen
)
393 oldDir
= CurrentDir(dirLock
);
395 d1(KPrintF("%s/%s/%ld: before av_open_input_file\n", __FILE__
, __FUNC__
, __LINE__
));
398 rc
= av_open_input_file(&avInfo
.avinf_pFormatContext
, iconName
, NULL
, 0, NULL
);
399 d1(KPrintF("%s/%s/%ld: rc=%d\n", __FILE__
, __FUNC__
, __LINE__
, rc
));
402 d1(KPrintF("%s/%s/%ld: av_open_input_file failed\n", __FILE__
, __FUNC__
, __LINE__
));
406 d1(KPrintF("%s/%s/%ld: before InitializeVideo\n", __FILE__
, __FUNC__
, __LINE__
));
408 if (!InitializeVideo(&avInfo
))
411 d1(KPrintF("%s/%s/%ld: after InitializeVideo\n", __FILE__
, __FUNC__
, __LINE__
));
413 if (!ReadVideoFrame(&avInfo
)) //before seeking, a frame has to be decoded
416 d1(KPrintF(__FILE__
"%s/%s/%ld: ReadVideoFrame success\n", __FILE__
, __FUNC__
, __LINE__
));
421 bmhdExternal
->bmh_Width
= avInfo
.avinf_pCodecContext
->width
;
422 bmhdExternal
->bmh_Height
= avInfo
.avinf_pCodecContext
->height
;
424 bmhdExternal
->bmh_Width
= 2;
425 bmhdExternal
->bmh_Height
= 2;
427 bmhdExternal
->bmh_Depth
= 24;
430 if (!FindInterestingFrame(&avInfo
))
433 if (!GetScaledVideoFrame(&avInfo
, ThumbnailWidth
, quality
, &vFrame
))
436 d1(KPrintF("%s/%s/%ld: vfr_width=%ld vfr_height=%ld vfr_lineSize=%ld\n", __FILE__
, __FUNC__
, __LINE__
, vFrame
.vfr_width
, vFrame
.vfr_height
, vFrame
.vfr_lineSize
));
438 if (vFrame
.vfr_width
> FILMHOLE_WIDTH
* 2)
440 OverlayFilmStrip(&avInfo
, &vFrame
);
443 ScreenDepth
= GetBitMapAttr(WBScreen
->RastPort
.BitMap
, BMA_DEPTH
);
445 DoRemap
= (ScreenDepth
<= 8) || (NULL
== CyberGfxBase
) || SupportedColors
<= 256;
447 d1(KPrintF("%s/%s/%ld: DoRemap=%ld\n", __FILE__
, __FUNC__
, __LINE__
, DoRemap
));
451 d1(KPrintF("%s/%s/%ld: SupportedColors=%lu ReservedColors=%ld\n", \
452 __FILE__
, __FUNC__
, __LINE__
, SupportedColors
, ReservedColors
));
454 Success
= GenerateRemappedThumbnail(wt
,
457 quality
, SupportedColors
, ReservedColors
,
458 ThumbnailWidth
, ThumbnailHeight
,
463 Success
= GenerateARGBThumbnail(wt
,
467 ThumbnailWidth
, ThumbnailHeight
,
472 d1(KPrintF("%s/%s/%ld: \n", __FILE__
, __FUNC__
, __LINE__
));
477 CleanupAVInfo(&avInfo
);
482 d1(KPrintF("%s/%s/%ld: END Success=%ld\n", __FILE__
, __FUNC__
, __LINE__
, Success
));
488 //----------------------------------------------------------------------------
495 //----------------------------------------------------------------------------
498 // Replacement for SAS/C library functions
511 #endif /* __amigaos4__ */
513 //-----------------------------------------------------------------------------
515 static BOOL
GenerateRemappedThumbnail(struct ScaWindowTask
*wt
,
516 CONST_STRPTR iconName
,
517 struct AVInfo
*avInfo
, struct VideoFrame
*vFrame
,
518 ULONG quality
, ULONG SupportedColors
, ULONG ReservedColors
,
519 ULONG ScaledWidth
, ULONG ScaledHeight
,
520 struct Screen
*WBScreen
, struct ScalosPreviewResult
*PVResult
)
522 BOOL Success
= FALSE
;
523 struct ARGBHeader argbTemp
= { 0, 0, NULL
};
524 struct ScalosBitMapAndColor
*sacSrc
= NULL
;
525 struct ScalosBitMapAndColor
*sacDest
= NULL
;
526 struct BitMap
*TempBM
= NULL
;
528 d1(KPrintF("%s/%s/%ld: START\n", __FILE__
, __FUNC__
, __LINE__
));
536 argbTemp
.argb_Width
= vFrame
->vfr_width
;
537 argbTemp
.argb_Height
= vFrame
->vfr_height
;
538 argbTemp
.argb_ImageData
= ScalosGfxCreateARGB(argbTemp
.argb_Width
, argbTemp
.argb_Height
, NULL
);
539 d1(KPrintF("%s/%s/%ld: argb_ImageData=%08lx\n", __FILE__
, __FUNC__
, __LINE__
, argbTemp
.argb_ImageData
));
540 if (NULL
== argbTemp
.argb_ImageData
)
543 // Fill argbSrc with image from vFrame
544 pLine
= argbTemp
.argb_ImageData
;
545 src
= avInfo
->avinf_pFrame
->data
[0];
546 for (y
= 0; y
< vFrame
->vfr_height
; y
++)
550 for (x
= 0; x
< vFrame
->vfr_width
; x
++)
553 pLine
->Green
= *src
++;
554 pLine
->Blue
= *src
++;
555 pLine
->Alpha
= (UBYTE
) ~0;
561 // Limit color depth to the number of colors supported by the icon
562 for (Depth
= 0; Depth
< 7 && (1 << Depth
) < SupportedColors
; Depth
++)
565 d1(KPrintF(__FILE__
"/%s/%ld: argb_ImageData: a=%ld r=%ld g=%ld b=%ld\n", \
566 __FUNC__
, __LINE__
, argbTemp
.argb_ImageData
->Alpha
, \
567 argbTemp
.argb_ImageData
->Red
, argbTemp
.argb_ImageData
->Green
, \
568 argbTemp
.argb_ImageData
->Blue
));
570 d1(KPrintF(__FILE__
"/%s/%ld: SupportedColors=%lu Depth=%lu ReservedColors=%lu\n", \
571 __FUNC__
, __LINE__
, SupportedColors
, Depth
, ReservedColors
));
573 PVResult
->spvr_sac
= ScalosGfxMedianCutTags(&argbTemp
, Depth
,
574 SCALOSGFX_MedianCutFlags
, SCALOSGFXFLAGF_MedianCut_FloydSteinberg
,
575 SCALOSGFX_MedianCutFriendBitMap
, NULL
,
576 SCALOSGFX_MedianCutReservedColors
, ReservedColors
,
578 d1(KPrintF(__FILE__
"/%s/%ld: sac=%08lx\n", __FUNC__
, __LINE__
, PVResult
->spvr_sac
));
580 d1(KPrintF(__FILE__
"/%s/%ld: sac_BitMap=%08lx\n", __FUNC__
, __LINE__
, PVResult
->spvr_sac
->sac_BitMap
));
581 d1(ByteDump((unsigned char *) PVResult
->spvr_sac
->sac_BitMap
, sizeof(struct BitMap
)));
589 ScalosGfxFreeARGB(&argbTemp
.argb_ImageData
);
590 ScalosGfxFreeSAC(sacSrc
);
591 ScalosGfxFreeSAC(sacDest
);
593 d1(KPrintF("%s/%s/%ld: END Success=%08lx\n", __FILE__
, __FUNC__
, __LINE__
, Success
));
598 //-----------------------------------------------------------------------------
600 static BOOL
GenerateARGBThumbnail(struct ScaWindowTask
*wt
,
601 CONST_STRPTR iconName
,
602 struct AVInfo
*avInfo
, struct VideoFrame
*vFrame
,
604 ULONG ScaledWidth
, ULONG ScaledHeight
,
605 struct ScalosPreviewResult
*PVResult
)
607 BOOL Success
= FALSE
;
608 struct ARGBHeader argbSrc
= { 0, 0, NULL
};
610 d1(KPrintF("%s/%s/%ld: START\n", __FILE__
, __FUNC__
, __LINE__
));
617 argbSrc
.argb_Width
= vFrame
->vfr_width
;
618 argbSrc
.argb_Height
= vFrame
->vfr_height
;
619 argbSrc
.argb_ImageData
= ScalosGfxCreateARGB(argbSrc
.argb_Width
, argbSrc
.argb_Height
, NULL
);
620 d1(KPrintF("%s/%s/%ld: argb_ImageData=%08lx\n", __FILE__
, __FUNC__
, __LINE__
, argbSrc
.argb_ImageData
));
621 if (NULL
== argbSrc
.argb_ImageData
)
624 // Fill argbSrc with image from vFrame
625 pLine
= argbSrc
.argb_ImageData
;
626 src
= avInfo
->avinf_pFrame
->data
[0];
627 for (y
= 0; y
< vFrame
->vfr_height
; y
++)
631 for (x
= 0; x
< vFrame
->vfr_width
; x
++)
634 pLine
->Green
= *src
++;
635 pLine
->Blue
= *src
++;
636 pLine
->Alpha
= (UBYTE
) ~0;
642 PVResult
->spvr_ARGBheader
= argbSrc
;
643 memset(&argbSrc
, 0, sizeof(argbSrc
));
649 ScalosGfxFreeARGB(&argbSrc
.argb_ImageData
);
651 d1(KPrintF("%s/%s/%ld: END Success=%ld\n", __FILE__
, __FUNC__
, __LINE__
, Success
));
656 //-----------------------------------------------------------------------------
658 static void CleanupAVInfo(struct AVInfo
*avInfo
)
660 d1(KPrintF("%s/%s/%ld: END\n", __FILE__
, __FUNC__
, __LINE__
));
662 d1(KPrintF("%s/%s/%ld: avinf_pCodecContext=%08lx avinf_CodecOpened=%ld\n", __FILE__
, __FUNC__
, __LINE__
, \
663 avInfo
->avinf_pCodecContext
, avInfo
->avinf_CodecOpened
));
664 if (avInfo
->avinf_CodecOpened
)
666 avcodec_close(avInfo
->avinf_pCodecContext
);
667 avInfo
->avinf_pCodecContext
= NULL
;
668 avInfo
->avinf_CodecOpened
= FALSE
;
670 d1(KPrintF("%s/%s/%ld: avinf_pFormatContext=%08lx\n", __FILE__
, __FUNC__
, __LINE__
, avInfo
->avinf_pFormatContext
));
671 if (avInfo
->avinf_pFormatContext
)
673 av_close_input_file(avInfo
->avinf_pFormatContext
);
674 avInfo
->avinf_pFormatContext
= NULL
;
676 d1(KPrintF("%s/%s/%ld: avinf_pFrame=%08lx\n", __FILE__
, __FUNC__
, __LINE__
, avInfo
->avinf_pFrame
));
677 if (avInfo
->avinf_pFrame
)
679 av_free(avInfo
->avinf_pFrame
);
680 avInfo
->avinf_pFrame
= NULL
;
682 d1(KPrintF("%s/%s/%ld: avinf_pRGBFrame=%08lx\n", __FILE__
, __FUNC__
, __LINE__
, avInfo
->avinf_pRGBFrame
));
683 if (avInfo
->avinf_pRGBFrame
)
685 av_free(avInfo
->avinf_pRGBFrame
);
686 avInfo
->avinf_pRGBFrame
= NULL
;
688 d1(KPrintF("%s/%s/%ld: avinf_Buffer=%08lx\n", __FILE__
, __FUNC__
, __LINE__
, avInfo
->avinf_Buffer
));
689 if (avInfo
->avinf_Buffer
)
691 free(avInfo
->avinf_Buffer
);
692 avInfo
->avinf_Buffer
= NULL
;
694 d1(KPrintF("%s/%s/%ld: END\n", __FILE__
, __FUNC__
, __LINE__
));
697 //-----------------------------------------------------------------------------
699 static BOOL
InitializeVideo(struct AVInfo
*avInfo
)
701 BOOL Success
= FALSE
;
704 d1(KPrintF("%s/%s/%ld: START\n", __FILE__
, __FUNC__
, __LINE__
));
706 // Retrieve stream information
707 if (av_find_stream_info(avInfo
->avinf_pFormatContext
) < 0)
709 d1(KPrintF("%s/%s/%ld: av_find_stream_info failed\n", __FILE__
, __FUNC__
, __LINE__
));
713 d1(KPrintF("%s/%s/%ld: nb_streams=%ld\n", __FILE__
, __FUNC__
, __LINE__
, avInfo
->avinf_pFormatContext
->nb_streams
));
714 if (avInfo
->avinf_pFormatContext
->nb_streams
< 1)
716 d1(KPrintF("%s/%s/%ld: no streams found\n", __FILE__
, __FUNC__
, __LINE__
));
720 // Find the first video stream
721 avInfo
->avinf_VideoStream
= av_find_default_stream_index(avInfo
->avinf_pFormatContext
);
723 d1(KPrintF("%s/%s/%ld: avinf_VideoStream=%ld\n", __FILE__
, __FUNC__
, __LINE__
, avInfo
->avinf_VideoStream
));
724 if (NO_STREAM
== avInfo
->avinf_VideoStream
)
726 d1(KPrintF("%s/%s/%ld: Could not find video stream\n", __FILE__
, __FUNC__
, __LINE__
));
730 avInfo
->avinf_pVideoStream
= avInfo
->avinf_pFormatContext
->streams
[avInfo
->avinf_VideoStream
];
732 // Remember pointer to codec context for the video stream
733 avInfo
->avinf_pCodecContext
= avInfo
->avinf_pVideoStream
->codec
;
735 // Find decoder for the video stream
736 avInfo
->avinf_pVideoCodec
= avcodec_find_decoder(avInfo
->avinf_pCodecContext
->codec_id
);
738 d1(KPrintF("%s/%s/%ld: avinf_pCodecContext=%08lx avinf_pVideoCodec=%08lx\n", \
739 __FILE__
, __FUNC__
, __LINE__
, avInfo
->avinf_pCodecContext
, avInfo
->avinf_pVideoCodec
));
740 if (NULL
== avInfo
->avinf_pVideoCodec
)
742 d1(KPrintF("%s/%s/%ld: Video Codec not found\n", __FILE__
, __FUNC__
, __LINE__
));
746 d1(KPrintF("%s/%s/%ld: Codec name=<%s>\n", __FILE__
, __FUNC__
, __LINE__
, avInfo
->avinf_pVideoCodec
->name
));
748 avInfo
->avinf_pCodecContext
->workaround_bugs
= 1;
749 avInfo
->avinf_pFormatContext
->flags
|= AVFMT_FLAG_GENPTS
;
750 if(avInfo
->avinf_pVideoCodec
->capabilities
& CODEC_CAP_TRUNCATED
)
751 avInfo
->avinf_pCodecContext
->flags
|= CODEC_FLAG_TRUNCATED
; /* we dont send complete frames */
754 d1(KPrintF("%s/%s/%ld: width=%ld height=%ld pix_fmt=%ld\n", __FILE__
, __FUNC__
, __LINE__
, \
755 avInfo
->avinf_pCodecContext
->width
, avInfo
->avinf_pCodecContext
->height
, \
756 avInfo
->avinf_pCodecContext
->pix_fmt
));
758 if (0 == avInfo
->avinf_pCodecContext
->width
)
764 if (avcodec_open(avInfo
->avinf_pCodecContext
, avInfo
->avinf_pVideoCodec
) < 0)
766 d1(KPrintF("%s/%s/%ld: avcodec_open failed\n", __FILE__
, __FUNC__
, __LINE__
));
769 avInfo
->avinf_CodecOpened
= TRUE
;
771 // Allocate video frame
772 avInfo
->avinf_pFrame
= avcodec_alloc_frame();
773 d1(KPrintF("%s/%s/%ld: avinf_pFrame=%08lx\n", __FILE__
, __FUNC__
, __LINE__
, avInfo
->avinf_pFrame
));
774 if (NULL
== avInfo
->avinf_pFrame
)
777 if (!AllocFrameData(&avInfo
->avinf_pRGBFrame
,
778 avInfo
->avinf_pCodecContext
->width
,
779 avInfo
->avinf_pCodecContext
->height
,
788 d1(KPrintF("%s/%s/%ld: END Success=%ld\n", __FILE__
, __FUNC__
, __LINE__
, Success
));
793 //-----------------------------------------------------------------------------
795 static BOOL
ReadVideoFrame(struct AVInfo
*avInfo
)
798 int frameFinished
= FALSE
;
801 d1(KPrintF("%s/%s/%ld: START\n", __FILE__
, __FUNC__
, __LINE__
));
803 av_init_packet(&packet
);
805 while (av_read_frame(avInfo
->avinf_pFormatContext
, &packet
) >= 0)
807 // Is this a packet from the video stream?
808 if (packet
.stream_index
== avInfo
->avinf_VideoStream
)
810 int size
= packet
.size
;
811 UBYTE
*buffer
= packet
.data
;
813 while ((size
> 0) && !frameFinished
)
817 bytesDecoded
= avcodec_decode_video(avInfo
->avinf_pCodecContext
,
818 avInfo
->avinf_pFrame
,
823 d1(KPrintF("%s/%s/%ld: packet.size=%d frameFinished=%ld bytesDecoded=%ld\n", \
824 __FILE__
, __FUNC__
, __LINE__
, packet
.size
, frameFinished
, bytesDecoded
));
825 d1(KPrintF("%s/%s/%ld: pix_fmt=%d width=%ld height=%ld\n", \
826 __FILE__
, __FUNC__
, __LINE__
, avInfo
->avinf_pCodecContext
->pix_fmt
, \
827 avInfo
->avinf_pCodecContext
->width
, avInfo
->avinf_pCodecContext
->height
));
829 if (bytesDecoded
< 0)
832 if (frameFinished
&& (bytesDecoded
>= 0))
834 struct SwsContext
*ImgConvertContext
;
839 sprintf(buffer
, "pts=%llu dts=%llu", packet
.pts
, packet
.dts
);
840 KPrintF("%s/%s/%ld: %s\n", __FILE__
, __FUNC__
, __LINE__
, buffer
); \
843 // Convert frame image from native format to RGB
844 ImgConvertContext
= sws_getContext(avInfo
->avinf_pCodecContext
->width
,
845 avInfo
->avinf_pCodecContext
->height
,
846 avInfo
->avinf_pCodecContext
->pix_fmt
,
847 avInfo
->avinf_pCodecContext
->width
,
848 avInfo
->avinf_pCodecContext
->height
,
855 if (NULL
== ImgConvertContext
)
858 rc
= sws_scale(ImgConvertContext
,
859 avInfo
->avinf_pFrame
->data
,
860 avInfo
->avinf_pFrame
->linesize
,
862 avInfo
->avinf_pCodecContext
->height
,
863 avInfo
->avinf_pRGBFrame
->data
,
864 avInfo
->avinf_pRGBFrame
->linesize
);
866 d1(KPrintF("%s/%s/%ld: \n", __FILE__
, __FUNC__
, __LINE__
));
868 sws_freeContext(ImgConvertContext
);
875 buffer
+= bytesDecoded
;
876 size
-= bytesDecoded
;
883 av_free_packet(&packet
);
889 d1(KPrintF("%s/%s/%ld: frameFinished=%ld\n", __FILE__
, __FUNC__
, __LINE__
, frameFinished
));
891 av_free_packet(&packet
);
893 d1(KPrintF("%s/%s/%ld: END\n", __FILE__
, __FUNC__
, __LINE__
));
895 return (BOOL
) frameFinished
;
898 //-----------------------------------------------------------------------------
900 static BOOL
GetScaledVideoFrame(struct AVInfo
*avInfo
, int scaledSize
,
901 ULONG quality
, struct VideoFrame
*videoFrame
)
903 BOOL Success
= FALSE
;
906 int scaledWidth
, scaledHeight
;
908 if (!ConvertAndScaleFrame(avInfo
, PIX_FMT_RGB24
, scaledSize
,
909 &scaledWidth
, &scaledHeight
, quality
))
912 d1(KPrintF("%s/%s/%ld: ConvertAndScaleFrame success\n", __FILE__
, __FUNC__
, __LINE__
));
914 videoFrame
->vfr_width
= scaledWidth
;
915 videoFrame
->vfr_height
= scaledHeight
;
916 videoFrame
->vfr_lineSize
= avInfo
->avinf_pFrame
->linesize
[0];
918 d1(KPrintF("%s/%s/%ld: vfr_width=%ld vfr_height=%ld vfr_lineSize=%ld\n", __FILE__
, __FUNC__
, __LINE__
, \
919 videoFrame
->vfr_width
, videoFrame
->vfr_height
, videoFrame
->vfr_lineSize
));
927 //-----------------------------------------------------------------------------
929 static BOOL
ConvertAndScaleFrame(struct AVInfo
*avInfo
, int pixFormat
,
930 int scaledSize
, int *scaledWidth
, int *scaledHeight
, ULONG quality
)
932 AVFrame
*convertedFrame
= NULL
;
933 struct SwsContext
*scaleContext
;
934 BOOL Success
= FALSE
;
940 ScaleFlags
= SWS_BICUBIC
;
941 else if (quality
> 5)
942 ScaleFlags
= SWS_BILINEAR
;
944 ScaleFlags
= SWS_FAST_BILINEAR
;
946 CalculateDimensions(avInfo
->avinf_pCodecContext
->width
,
947 avInfo
->avinf_pCodecContext
->height
,
951 d1(KPrintF("%s/%s/%ld: width=%ld height=%ld\n", __FILE__
, __FUNC__
, __LINE__
,
952 avInfo
->avinf_pCodecContext
->width
, avInfo
->avinf_pCodecContext
->height
));
953 d1(KPrintF("%s/%s/%ld: scaledWidth=%ld scaledHeight=%ld\n", \
954 __FILE__
, __FUNC__
, __LINE__
, *scaledWidth
, *scaledHeight
));
958 const UBYTE
*p
= avInfo
->avinf_pFrame
->data
[0]; \
960 for (n
= 0; n
< avInfo
->avinf_pCodecContext
->height
; n
++) \
962 ByteDump(p
, avInfo
->avinf_pFrame
->linesize
[0]); \
963 p
+= avInfo
->avinf_pFrame
->linesize
[0]; \
967 scaleContext
= sws_getContext(avInfo
->avinf_pCodecContext
->width
,
968 avInfo
->avinf_pCodecContext
->height
,
969 avInfo
->avinf_pCodecContext
->pix_fmt
,
978 d1(KPrintF("%s/%s/%ld: scaleContext=%08lx\n", __FILE__
, __FUNC__
, __LINE__
, scaleContext
));
979 if (NULL
== scaleContext
)
982 if (!AllocFrameData(&convertedFrame
, *scaledWidth
, *scaledHeight
, pixFormat
))
985 d1(KPrintF("%s/%s/%ld: convertedFrame=%08lx\n", __FILE__
, __FUNC__
, __LINE__
, convertedFrame
));
986 if (NULL
== convertedFrame
)
989 sws_scale(scaleContext
,
990 avInfo
->avinf_pFrame
->data
,
991 avInfo
->avinf_pFrame
->linesize
,
993 avInfo
->avinf_pCodecContext
->height
,
994 convertedFrame
->data
,
995 convertedFrame
->linesize
);
1001 sws_freeContext(scaleContext
);
1005 av_free(avInfo
->avinf_pFrame
);
1006 avInfo
->avinf_pFrame
= convertedFrame
;
1012 //-----------------------------------------------------------------------------
1014 static void CalculateDimensions(int srcWidth
, int srcHeight
, int squareSize
, int *destWidth
, int *destHeight
)
1016 if (srcWidth
> srcHeight
)
1018 *destWidth
= squareSize
;
1019 *destHeight
= (int) ((float)(squareSize
) / srcWidth
* srcHeight
);
1023 *destWidth
= (int)((float)(squareSize
) / srcHeight
* srcWidth
);
1024 *destHeight
= squareSize
;
1028 //-----------------------------------------------------------------------------
1030 static BOOL
AllocFrameData(AVFrame
**avFrame
, int width
, int height
, int pixFormat
)
1034 *avFrame
= avcodec_alloc_frame();
1035 d1(KPrintF("%s/%s/%ld: *avFrame=%08lx\n", __FILE__
, __FUNC__
, __LINE__
, *avFrame
));
1036 if (NULL
== *avFrame
)
1039 numBytes
= avpicture_get_size(pixFormat
, width
, height
);
1040 d1(KPrintF("%s/%s/%ld: numBytes=%ld\n", __FILE__
, __FUNC__
, __LINE__
, numBytes
));
1042 if (0 != avpicture_alloc((AVPicture
*) *avFrame
, pixFormat
, width
, height
))
1044 d1(KPrintF("%s/%s/%ld: avpicture_alloc failed\n", __FILE__
, __FUNC__
, __LINE__
));
1051 //-----------------------------------------------------------------------------
1053 static BOOL
VideoSeekFrame(struct AVInfo
*avInfo
, float timeInSeconds
)
1056 // int64_t timestamp = (int64_t) (10 * AV_TIME_BASE * timeInSeconds);
1057 int64_t timestamp
= (int64_t) (AV_TIME_BASE
* timeInSeconds
);
1065 sprintf(buffer
, "timeInSeconds=%f timestamp=%llu", timeInSeconds
, timestamp
); \
1066 KPrintF("%s/%s/%ld: %s\n", __FILE__
, __FUNC__
, __LINE__
, buffer
); \
1069 rc
= av_seek_frame(avInfo
->avinf_pFormatContext
, -1, timestamp
, 0);
1070 d1(KPrintF("%s/%s/%ld: rc=%ld\n", __FILE__
, __FUNC__
, __LINE__
, rc
));
1075 foundFrame
= ReadVideoFrame(avInfo
);
1077 d1(KPrintF("%s/%s/%ld: foundFrame=%ld count=%ld\n", __FILE__
, __FUNC__
, __LINE__
, foundFrame
, ++count
));
1078 } while (!foundFrame
/* && !avInfo->avinf_pFrame->key_frame */ && ++count
< 20);
1083 sprintf(buffer
, "pts=%f coded_picture_number=%d display_picture_number=%d", \
1084 (float) (avInfo
->avinf_pFrame
->pts
* avInfo
->avinf_pCodecContext
->time_base
.num
) \
1085 / (float) avInfo
->avinf_pCodecContext
->time_base
.den
, \
1086 avInfo
->avinf_pFrame
->coded_picture_number
, \
1087 avInfo
->avinf_pFrame
->display_picture_number
); \
1088 KPrintF("%s/%s/%ld: %s\n", __FILE__
, __FUNC__
, __LINE__
, buffer
); \
1095 //-----------------------------------------------------------------------------
1097 static void OverlayFilmStrip(struct AVInfo
*avInfo
, struct VideoFrame
*videoFrame
)
1099 static const UBYTE filmHole
[FILMHOLE_WIDTH
* FILMHOLE_HEIGHT
* 3] =
1101 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1102 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1103 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1104 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x23, 0x23, 0x7a, 0x7a, 0x7a, 0x83, 0x83, 0x83, 0x8c, 0x8c, 0x8c, 0x90, 0x90, 0x90, 0x8e, 0x8e, 0x8e, 0x52, 0x52, 0x52, 0x00, 0x00, 0x00,
1105 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x6e, 0x6e, 0x83, 0x83, 0x83, 0x93, 0x93, 0x93, 0xa3, 0xa3, 0xa3, 0xab, 0xab, 0xab, 0xa8, 0xa8, 0xa8, 0x9b, 0x9b, 0x9b, 0x00, 0x00, 0x00,
1106 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x72, 0x72, 0x72, 0x8e, 0x8e, 0x8e, 0xa4, 0xa4, 0xa4, 0xbb, 0xbb, 0xbb, 0xc4, 0xc4, 0xc4, 0xc1, 0xc1, 0xc1, 0xaf, 0xaf, 0xaf, 0x00, 0x00, 0x00,
1107 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x3e, 0x3e, 0x90, 0x90, 0x90, 0xa6, 0xa6, 0xa6, 0xbe, 0xbe, 0xbe, 0xc8, 0xc8, 0xc8, 0xc4, 0xc4, 0xc4, 0x8e, 0x8e, 0x8e, 0x00, 0x00, 0x00,
1108 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x07, 0x07, 0x09, 0x09, 0x09, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1109 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1110 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1114 int filmHoleIndex
= 0;
1115 int offset
= (videoFrame
->vfr_width
* 3) - 3;
1116 UBYTE
*pRGB
= avInfo
->avinf_pFrame
->data
[0];
1119 for (i
= 0; i
< videoFrame
->vfr_height
; ++i
)
1123 for (j
= 0; j
< FILMHOLE_WIDTH
* 3; j
+=3)
1125 int currentFilmHoleIndex
= filmHoleIndex
+ j
;
1127 pRGB
[frameIndex
+ j
] = filmHole
[currentFilmHoleIndex
];
1128 pRGB
[frameIndex
+ j
+ 1] = filmHole
[currentFilmHoleIndex
+ 1];
1129 pRGB
[frameIndex
+ j
+ 2] = filmHole
[currentFilmHoleIndex
+ 2];
1131 pRGB
[frameIndex
+ offset
- j
] = filmHole
[currentFilmHoleIndex
];
1132 pRGB
[frameIndex
+ offset
- j
+ 1] = filmHole
[currentFilmHoleIndex
+ 1];
1133 pRGB
[frameIndex
+ offset
- j
+ 2] = filmHole
[currentFilmHoleIndex
+ 2];
1135 frameIndex
+= videoFrame
->vfr_lineSize
;
1136 filmHoleIndex
= (i
% FILMHOLE_HEIGHT
) * FILMHOLE_WIDTH
* 3;
1140 //-----------------------------------------------------------------------------
1142 #define BORING_IMAGE_VARIANCE 512.0 /* Tweak this if necessary */
1144 /* This function attempts to detect images that are mostly solid images
1145 * It does this by calculating the statistical variance of the
1146 * black-and-white image */
1147 static BOOL
IsInterestingFrame(const struct AVInfo
*avInfo
)
1149 /* We're gonna assume 8-bit samples. If anyone uses anything different,
1150 * it doesn't really matter cause it's gonna be ugly anyways */
1151 float variance
= 0.0f
;
1152 float average
= 0.0f
;
1153 ULONG NumberOfSamples
;
1156 /* FIXME: If this proves to be a performance issue, this function
1157 * can be modified to perhaps only check 3 rows. I doubt this'll
1158 * be a problem though. */
1160 NumberOfSamples
= avInfo
->avinf_pCodecContext
->width
* avInfo
->avinf_pCodecContext
->height
;
1161 NumberOfSamples
/= 2;
1163 // Iterate through the RGB image to calculate average
1164 for (y
= 0; y
< avInfo
->avinf_pCodecContext
->height
; y
+= 2)
1166 const UBYTE
*pBuffer
= avInfo
->avinf_pRGBFrame
->data
[0] + y
* avInfo
->avinf_pRGBFrame
->linesize
[0];
1169 for (x
= 0; x
< avInfo
->avinf_pCodecContext
->width
; x
++)
1171 average
+= (float) (pBuffer
[0] + pBuffer
[1] + pBuffer
[2]);
1175 average
/= ((float) (3 * NumberOfSamples
));
1177 /* Calculate the variance */
1178 for (y
= 0; y
< avInfo
->avinf_pCodecContext
->height
; y
++)
1180 const UBYTE
*pBuffer
= avInfo
->avinf_pRGBFrame
->data
[0] + y
* avInfo
->avinf_pRGBFrame
->linesize
[0];
1183 for (x
= 0; x
< avInfo
->avinf_pCodecContext
->width
; x
++)
1185 float tmp
= (float) ((pBuffer
[0] + pBuffer
[1] + pBuffer
[2]) / 3) - average
;
1187 variance
+= tmp
* tmp
;
1191 variance
/= ((float) (NumberOfSamples
- 1));
1195 sprintf(buffer
, "average=%f variance=%f", average
, variance
); \
1196 KPrintF("%s/%s/%ld: %s\n", __FILE__
, __FUNC__
, __LINE__
, buffer
); \
1199 d1(KPrintF("%s/%s/%ld: IsInterestingFrame=%ld\n", __FILE__
, __FUNC__
, __LINE__
, (variance
> BORING_IMAGE_VARIANCE
)));
1201 return (variance
> BORING_IMAGE_VARIANCE
);
1204 //-----------------------------------------------------------------------------
1206 static BOOL
FindInterestingFrame(struct AVInfo
*avInfo
)
1209 float framePosition
= 1.2;
1210 float FramePositionStep
= 0.25;
1212 for (n
= 0; !IsInterestingFrame(avInfo
) && n
< 10; n
++)
1214 d1(KPrintF("%s/%s/%ld: n=%ld\n", __FILE__
, __FUNC__
, __LINE__
, n
));
1215 if (!VideoSeekFrame(avInfo
, framePosition
))
1217 d1(KPrintF("%s/%s/%ld: VideoSeekFrame failed n=%ld\n", __FILE__
, __FUNC__
, __LINE__
, n
));
1220 framePosition
+= FramePositionStep
;
1221 FramePositionStep
+= FramePositionStep
; // double step size on each loop
1224 d1(KPrintF("%s/%s/%ld: Success n=%ld\n", __FILE__
, __FUNC__
, __LINE__
, n
));
1229 //-----------------------------------------------------------------------------
1231 static void av_log_dummy_callback(void* ptr
, int level
, const char* fmt
, va_list vl
)
1236 d1(KPrintF("%s/%s/%ld: fmt=<%s> level=%ld\n", __FILE__
, __FUNC__
, __LINE__
, fmt
, level
));
1242 vsnprintf(buf
, sizeof(buf
), fmt
, vl
);
1243 d1(KPrintF("%s/%s/%ld: %s\n", __FILE__
, __FUNC__
, __LINE__
, buf
));
1247 //-----------------------------------------------------------------------------
1255 //-----------------------------------------------------------------------------
1258 static void ByteDump(const unsigned char *Data
, size_t Length
)
1260 unsigned long count
;
1261 unsigned char Line
[80], *lp
;
1264 for (count
=0; count
<Length
; count
++)
1266 *lp
++ = isprint(*Data
) ? *Data
: '.';
1267 KPrintF("%02lx ", (ULONG
) *Data
++);
1268 if ((count
+1) % 16 == 0)
1272 KPrintF("\t%s\n", Line
);
1277 while (count
% 16 != 0)
1282 KPrintF("\t%s\n", Line
);
1284 #endif /* BYTEDUMP */
1286 //-----------------------------------------------------------------------------