From e2768672e7881b4cc58106fb9763c57057345c0c Mon Sep 17 00:00:00 2001 From: codestation Date: Thu, 2 Jan 2014 01:52:11 -0430 Subject: [PATCH] Change the read method of ffmpeg from filename to buffer to avoid passing a filename with incorrect encoding to avformat_open_input. Increased the size of photo thumbnails a little. --- src/avdecoder.cpp | 52 ++++++++++++++++++++++++++++++++++++++++++++--- src/avdecoder.h | 5 +++++ src/utils.cpp | 2 +- 3 files changed, 55 insertions(+), 4 deletions(-) diff --git a/src/avdecoder.cpp b/src/avdecoder.cpp index 2560063..39ca434 100644 --- a/src/avdecoder.cpp +++ b/src/avdecoder.cpp @@ -28,28 +28,70 @@ AVDecoder::AvInit init; AVDecoder::AVDecoder() : - pFormatCtx(NULL) + pFormatCtx(NULL), file(NULL) { } AVDecoder::~AVDecoder() { if(pFormatCtx) { + av_free(pFormatCtx->pb->buffer); + av_free(pFormatCtx->pb); avformat_close_input(&pFormatCtx); } + if(file) { + file->close(); + delete file; + } +} + +int AVDecoder::readFunction(void* opaque, uint8_t* buf, int buf_size) +{ + QIODevice* stream = (QIODevice*)opaque; + int numBytes = stream->read((char*)buf, buf_size); + return numBytes; +} + +int64_t AVDecoder::seekFunction(void* opaque, int64_t offset, int whence) +{ + if (whence == AVSEEK_SIZE) { + return -1; // I don't know "size of my handle in bytes" + } + QIODevice* stream = (QIODevice*)opaque; + if (stream->isSequential()) { + return -1; // cannot seek a sequential stream + } + if (! stream->seek(offset) ) { + return -1; + } + return stream->pos(); } bool AVDecoder::open(const QString filename) { - if(avformat_open_input(&pFormatCtx, QFile::encodeName(filename).constData(), NULL, NULL) != 0) { + file = new QFile(filename); + if(!file->open(QIODevice::ReadOnly)) { + return false; + } + const int ioBufferSize = 32768; + unsigned char *ioBuffer = (unsigned char *)av_malloc(ioBufferSize + FF_INPUT_BUFFER_PADDING_SIZE); + AVIOContext *avioContext = avio_alloc_context(ioBuffer, ioBufferSize, 0, (void*)(file), &AVDecoder::readFunction, NULL, &AVDecoder::seekFunction); + pFormatCtx = avformat_alloc_context(); + pFormatCtx->pb = avioContext; + + + if(avformat_open_input(&pFormatCtx, "dummy", NULL, NULL) != 0) { + av_free(avioContext->buffer); + av_free(avioContext); return false; } if(avformat_find_stream_info(pFormatCtx, NULL) < 0) { + av_free(avioContext->buffer); + av_free(avioContext); avformat_close_input(&pFormatCtx); return false; } - return true; } @@ -273,6 +315,10 @@ QByteArray AVDecoder::getVideoThumbnail(int width, int height) void AVDecoder::close() { + av_free(pFormatCtx->pb->buffer); + av_free(pFormatCtx->pb); avformat_close_input(&pFormatCtx); pFormatCtx = NULL; + file->close(); + file = NULL; } diff --git a/src/avdecoder.h b/src/avdecoder.h index f022f6a..e152d05 100644 --- a/src/avdecoder.h +++ b/src/avdecoder.h @@ -20,6 +20,7 @@ #ifndef AVDECODER_H #define AVDECODER_H +#include #include #include @@ -62,7 +63,11 @@ private: void AVFrameToQImage(AVFrame &frame, QImage &image, int width, int height); AVFrame *getDecodedFrame(AVCodecContext *pCodecCtx, int stream_index); + static int readFunction(void* opaque, uint8_t* buf, int buf_size); + static int64_t seekFunction(void* opaque, int64_t offset, int whence); + AVFormatContext *pFormatCtx; + QFile *file; }; #endif // AVDECODER_H diff --git a/src/utils.cpp b/src/utils.cpp index 14e8847..22059f0 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -127,7 +127,7 @@ QByteArray getThumbnail(const QString &path, DataType type, metadata_t *metadata if(img.load(path)) { QBuffer buffer(&data); buffer.open(QIODevice::WriteOnly); - QImage result = img.scaled(213, 120, Qt::KeepAspectRatio, Qt::FastTransformation); + QImage result = img.scaled(240, 136, Qt::KeepAspectRatio, Qt::FastTransformation); result.save(&buffer, "JPEG"); metadata->data.thumbnail.width = result.width(); metadata->data.thumbnail.height = result.height();