Skip to content

Commit 94da09c

Browse files
committed
FFmpegImage: Implement Thumbnail extract (still wip cause of ARGB)
1 parent dd1835f commit 94da09c

File tree

2 files changed

+107
-3
lines changed

2 files changed

+107
-3
lines changed

xbmc/guilib/FFmpegImage.cpp

Lines changed: 106 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,110 @@ 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+
return false;
349+
}
350+
351+
AVFrame* frame = av_frame_alloc();
352+
if (!frame)
353+
{
354+
CLog::Log(LOGERROR, "Could not generate thumbnail: %s", destFile.c_str());
355+
av_free(m_outputBuffer);
356+
m_outputBuffer = NULL;
357+
avcodec_close(avOutctx);
358+
return false;
359+
}
360+
361+
frame->pts = 1;
362+
frame->quality = avOutctx->global_quality;
363+
frame->data[0] = (uint8_t*) bufferin;
364+
// i don't understand those two ... as ARGB is ARGBARGBARGB
365+
frame->data[1] = (uint8_t*) bufferin;
366+
frame->data[2] = (uint8_t*) bufferin;
367+
frame->height = height;
368+
frame->width = width;
369+
frame->linesize[0] = pitch;
370+
// see above
371+
frame->linesize[1] = pitch;
372+
frame->linesize[2] = pitch;
373+
frame->format = AV_PIX_FMT_ARGB;
374+
375+
int got_package = 0;
376+
AVPacket avpkt;
377+
av_init_packet(&avpkt);
378+
avpkt.data = m_outputBuffer;
379+
avpkt.size = internalBufOutSize;
380+
381+
if ((avcodec_encode_video2(avOutctx, &avpkt, frame, &got_package) < 0) || (got_package == 0))
382+
{
383+
CLog::Log(LOGERROR, "Could not generate thumbnail: %s", destFile.c_str());
384+
av_free(m_outputBuffer);
385+
m_outputBuffer = NULL;
386+
av_frame_free(&frame);
387+
avcodec_close(avOutctx);
388+
avcodec_free_context(&avOutctx);
389+
return false;
390+
}
391+
392+
FILE* fout = fopen("/home/fritsch/scheisshaus.jpg", "wb");
393+
if(!fout)
394+
{
395+
CLog::Log(LOGERROR, "Could not generate thumbnail: %s", destFile.c_str());
396+
av_free(m_outputBuffer);
397+
m_outputBuffer = NULL;
398+
av_frame_free(&frame);
399+
avcodec_close(avOutctx);
400+
avcodec_free_context(&avOutctx);
401+
return false;
402+
}
403+
fwrite(m_outputBuffer, 1, avpkt.size, fout);
404+
fclose(fout);
405+
406+
bufferoutSize = avpkt.size;
407+
bufferout = m_outputBuffer;
408+
409+
av_frame_free(&frame);
410+
avcodec_close(avOutctx);
411+
avcodec_free_context(&avOutctx);
412+
413+
return true;
313414
}
314415

315416
void CFFmpegImage::ReleaseThumbnailBuffer()
316417
{
418+
av_free(m_outputBuffer);
419+
m_outputBuffer = NULL;
317420
}

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)