Skip to content

Commit d4380bc

Browse files
committed
FFmpegImage: Implement Thumbnail extract (still wip cause of ARGB - which segfaults)
1 parent dd1835f commit d4380bc

File tree

2 files changed

+89
-3
lines changed

2 files changed

+89
-3
lines changed

xbmc/guilib/FFmpegImage.cpp

Lines changed: 88 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -101,12 +101,14 @@ CFFmpegImage::CFFmpegImage()
101101
{
102102
m_hasAlpha = false;
103103
m_pFrame = nullptr;
104-
104+
m_outputBuffer = nullptr;
105105
}
106106

107107
CFFmpegImage::~CFFmpegImage()
108108
{
109109
av_frame_free(&m_pFrame);
110+
// someone could have forgotten to call us
111+
free(m_outputBuffer);
110112
}
111113

112114
bool CFFmpegImage::LoadImageFromMemory(unsigned char* buffer, unsigned int bufSize,
@@ -243,7 +245,7 @@ bool CFFmpegImage::Decode(unsigned char * const pixels, unsigned int width, unsi
243245

244246
bool needsCopy = false;
245247
int pixelsSize = pitch * height;
246-
if (size == pixelsSize && pitch == pictureRGB->linesize[0])
248+
if (size == pixelsSize && (int) pitch == pictureRGB->linesize[0])
247249
{
248250
// We can use the pixels buffer directly
249251
pictureRGB->data[0] = pixels;
@@ -309,9 +311,92 @@ bool CFFmpegImage::CreateThumbnailFromSurface(unsigned char* bufferin, unsigned
309311
unsigned char* &bufferout,
310312
unsigned int &bufferoutSize)
311313
{
312-
return false;
314+
315+
if (format != XB_FMT_A8R8G8B8)
316+
{
317+
CLog::Log(LOGNOTICE, "Supplied format: %d is not supported.", format);
318+
}
319+
AVCodec* codec = avcodec_find_encoder(CODEC_ID_MJPEG);
320+
if (!codec)
321+
return false;
322+
323+
AVCodecContext* avOutctx = avcodec_alloc_context3(codec);
324+
if (!avOutctx)
325+
return false;
326+
327+
avOutctx->height = height;
328+
avOutctx->width = width;
329+
avOutctx->time_base.num = 1;
330+
avOutctx->time_base.den = 1;
331+
avOutctx->pix_fmt = PIX_FMT_YUVJ420P;
332+
333+
unsigned int internalBufOutSize = 0;
334+
335+
internalBufOutSize = avpicture_get_size(avOutctx->pix_fmt, avOutctx->width, avOutctx->height);
336+
m_outputBuffer = (uint8_t*) av_malloc(internalBufOutSize);
337+
if (!m_outputBuffer)
338+
{
339+
avcodec_free_context(&avOutctx);
340+
return false;
341+
}
342+
343+
if (avcodec_open2(avOutctx, codec, NULL) < 0 )
344+
{
345+
CLog::Log(LOGERROR, "Could not generate thumbnail: %s", destFile.c_str());
346+
av_free(m_outputBuffer);
347+
m_outputBuffer = NULL;
348+
avcodec_free_context(&avOutctx);
349+
return false;
350+
}
351+
352+
AVFrame* frame = av_frame_alloc();
353+
if (!frame)
354+
{
355+
CLog::Log(LOGERROR, "Could not generate thumbnail: %s", destFile.c_str());
356+
av_free(m_outputBuffer);
357+
m_outputBuffer = NULL;
358+
avcodec_close(avOutctx);
359+
avcodec_free_context(&avOutctx);
360+
return false;
361+
}
362+
363+
frame->pts = 1;
364+
frame->quality = avOutctx->global_quality;
365+
frame->data[0] = (uint8_t*) bufferin;
366+
frame->height = height;
367+
frame->width = width;
368+
frame->linesize[0] = pitch;
369+
frame->format = AV_PIX_FMT_ARGB;
370+
371+
int got_package = 0;
372+
AVPacket avpkt;
373+
av_init_packet(&avpkt);
374+
avpkt.data = m_outputBuffer;
375+
avpkt.size = internalBufOutSize;
376+
377+
if ((avcodec_encode_video2(avOutctx, &avpkt, frame, &got_package) < 0) || (got_package == 0))
378+
{
379+
CLog::Log(LOGERROR, "Could not generate thumbnail: %s", destFile.c_str());
380+
av_free(m_outputBuffer);
381+
m_outputBuffer = NULL;
382+
av_frame_free(&frame);
383+
avcodec_close(avOutctx);
384+
avcodec_free_context(&avOutctx);
385+
return false;
386+
}
387+
388+
bufferoutSize = avpkt.size;
389+
bufferout = m_outputBuffer;
390+
391+
av_frame_free(&frame);
392+
avcodec_close(avOutctx);
393+
avcodec_free_context(&avOutctx);
394+
395+
return true;
313396
}
314397

315398
void CFFmpegImage::ReleaseThumbnailBuffer()
316399
{
400+
av_free(m_outputBuffer);
401+
m_outputBuffer = NULL;
317402
}

xbmc/guilib/FFmpegImage.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,4 +53,5 @@ class CFFmpegImage : public IImage
5353
static AVPixelFormat ConvertFormats(AVFrame* frame);
5454

5555
AVFrame* m_pFrame;
56+
uint8_t* m_outputBuffer;
5657
};

0 commit comments

Comments
 (0)