【发布时间】:2014-05-26 15:33:22
【问题描述】:
我需要翻译包含此函数的图像处理 SDK 的 C 标头:
#define SDK_API __declspec(dllimport)
SDK_API BOOL WINAPI SetSourceYUVJ420(HANDLE Display, BYTE **YUV420P, int *LineSize, int srcWidth, int srcHeight);
该函数用于将 YUVJ420 帧传递给 SDK。
在我的代码中,帧存储在 PAVPicture 记录中(在 FFVCL 组件库中定义),其中:
data: array[0..7] of pbyte;
linesize: array[0..7] of integer;
解码视频帧后,FFVCL 会触发一个事件,在该事件中该帧可用作 PAVPicture 类型的 APicture。
我是这样翻译的:
function SetSourceYUVJ420(Display: UIntPtr; YUV420P: Pointer; LineSize: Pointer; srcWidth, srcHeight: integer): boolean stdcall; external 'SDK.DLL' name '_SetSourceYUVJ420@20';
并像这样使用它:
SetSourceYUVJ420(Display, @APicture.data[0], @APicture.linesize[0], W, H);
.. 但是这样我会丢失一些指针/地址。
SDK 文档为中式英语且已过时。我确实有一个 C 示例,它使用 FFMpeg 进行解码,当一帧完成时,部分 pFrame(类型 AVFrame)被传递给 SDK:
unsigned WINAPI MYTest() {
AVFormatContext *pFormatCtx;
unsigned int i, videoStream;
AVCodecContext *pCodecCtx;
AVCodec *pCodec;
AVFrame *pFrame = NULL;
AVPacket packet;
int frameFinished;
av_register_all();
pFormatCtx = avformat_alloc_context();
avformat_open_input(&pFormatCtx, "..\\..\\images\\Test.mp4",NULL,NULL);
av_find_stream_info(pFormatCtx);
videoStream=-1;
for (i=0; i < pFormatCtx->nb_streams; i++) {
if (pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
videoStream = i;
break;
}
}
// Get a pointer to the codec context for the video stream
pCodecCtx = pFormatCtx->streams[videoStream]->codec;
pCodec = avcodec_find_decoder(pCodecCtx->codec_id);
// Open codec
avcodec_open2(pCodecCtx, pCodec,0) < 0;
// Allocate video frame
pFrame = av_frame_alloc();
// Read frames and save first five frames to disk
i = 0;
BOOL fSetBuffer = FALSE;
BOOL f = FALSE;
while (av_read_frame(pFormatCtx, &packet) >= 0 && !fTerminate) {
// Is this a packet from the video stream?
if(packet.stream_index==videoStream) {
// Decode video frame
avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, &packet);
if ( frameFinished ) {
// This function told SDK, new video imcoming, with video format is YUV420
SetSourceYUVJ420(gDisplay, pFrame->data, pFrame->linesize, pCodecCtx->width, pCodecCtx->height);
}
}
// Free the packet that was allocated by av_read_frame
av_free_packet(&packet);
}
// Free the YUV frame
av_free(pFrame);
// Close the codec
avcodec_close(pCodecCtx);
// Close the video file
avformat_close_input(&pFormatCtx);
return TRUE;
}
这是 AVFrame 的声明(取自 FFMPeg 的 frame.h):
typedef struct AVFrame {
#define AV_NUM_DATA_POINTERS 8
/**
* pointer to the picture/channel planes.
* This might be different from the first allocated byte
*
* Some decoders access areas outside 0,0 - width,height, please
* see avcodec_align_dimensions2(). Some filters and swscale can read
* up to 16 bytes beyond the planes, if these filters are to be used,
* then 16 extra bytes must be allocated.
*/
uint8_t *data[AV_NUM_DATA_POINTERS];
/**
* For video, size in bytes of each picture line.
* For audio, size in bytes of each plane.
*
* For audio, only linesize[0] may be set. For planar audio, each channel
* plane must be the same size.
*
* For video the linesizes should be multiplies of the CPUs alignment
* preference, this is 16 or 32 for modern desktop CPUs.
* Some code requires such alignment other code can be slower without
* correct alignment, for yet other it makes no difference.
*
* @note The linesize may be larger than the size of usable data -- there
* may be extra padding present for performance reasons.
*/
int linesize[AV_NUM_DATA_POINTERS];
<SNIP>
} AVFrame;
问题:
- 如何正确翻译这个 C 函数定义
- 如何使用提供的 FFVCL 类型 PAVPicture 调用此函数
【问题讨论】:
-
这个问题无法回答。您还需要指定参数的语义。例如,
int*是什么?由 ref 或数组传递的单个 int。谁分配内存?你有 C++ 代码的文档吗?一些示例 C++ 调用代码会有所帮助。 -
请注意,四个 32 位参数通常会产生 @_16 后缀,而不是 @_20(添加下划线以避免 SO 通知系统)
-
这表明这可能是一个实例方法
-
我编辑了问题以添加更多信息和一些 C 调用代码。
标签: delphi header-files delphi-xe4 yuv