@@ -101,12 +101,14 @@ CFFmpegImage::CFFmpegImage()
101101{
102102 m_hasAlpha = false ;
103103 m_pFrame = nullptr ;
104-
104+ m_outputBuffer = nullptr ;
105105}
106106
107107CFFmpegImage::~CFFmpegImage ()
108108{
109109 av_frame_free (&m_pFrame);
110+ // someone could have forgotten to call us
111+ free (m_outputBuffer);
110112}
111113
112114bool 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
315416void CFFmpegImage::ReleaseThumbnailBuffer ()
316417{
418+ av_free (m_outputBuffer);
419+ m_outputBuffer = NULL ;
317420}
0 commit comments