Line 0
Link Here
|
|
|
1 |
diff --git a/CMakeLists.txt b/CMakeLists.txt |
2 |
index 48eed64d76f0542327c8dbce9644e5cc898c8cbc..3c761fa584497e6aba9065e195533b1bf8498648 100644 |
3 |
--- CMakeLists.txt |
4 |
+++ CMakeLists.txt |
5 |
@@ -27,7 +27,7 @@ set( ffmpegthumbs_PART_SRCS |
6 |
|
7 |
kde4_add_plugin(ffmpegthumbs ${ffmpegthumbs_PART_SRCS}) |
8 |
|
9 |
-target_link_libraries(ffmpegthumbs ${KDE4_KIO_LIBS} ${AVUTIL_LIBRARIES} ${AVFORMAT_LIBRARIES} ${AVCODEC_LIBRARIES} ${SWSCALE_LIBRARIES} ) |
10 |
+target_link_libraries(ffmpegthumbs ${KDE4_KIO_LIBS} ${AVUTIL_LIBRARIES} ${AVFILTER_LIBRARIES} ${AVFORMAT_LIBRARIES} ${AVCODEC_LIBRARIES} ${SWSCALE_LIBRARIES} ) |
11 |
|
12 |
install(TARGETS ffmpegthumbs DESTINATION ${PLUGIN_INSTALL_DIR}) |
13 |
|
14 |
diff --git a/cmake/FindFFmpeg.cmake b/cmake/FindFFmpeg.cmake |
15 |
index 27c6b16de7cfd7514a9a2c273dcd242670248613..915ab5f9f9618c460560342b564963e701a5efd8 100644 |
16 |
--- cmake/FindFFmpeg.cmake |
17 |
+++ cmake/FindFFmpeg.cmake |
18 |
@@ -99,6 +99,7 @@ if (NOT FFMPEG_LIBRARIES) |
19 |
|
20 |
# Check for all possible component. |
21 |
find_component(AVCODEC libavcodec avcodec libavcodec/avcodec.h) |
22 |
+ find_component(AVFILTER libavfilter avfilter libavfilter/avfilter.h) |
23 |
find_component(AVFORMAT libavformat avformat libavformat/avformat.h) |
24 |
find_component(AVDEVICE libavdevice avdevice libavdevice/avdevice.h) |
25 |
find_component(AVUTIL libavutil avutil libavutil/avutil.h) |
26 |
diff --git a/ffmpegthumbnailer/moviedecoder.h b/ffmpegthumbnailer/moviedecoder.h |
27 |
index 288892685b6ae6946f158deacab1eeded5745cb6..b4a76b81724dd5956eb2be61ab7470b2ed351a4c 100644 |
28 |
--- ffmpegthumbnailer/moviedecoder.h |
29 |
+++ ffmpegthumbnailer/moviedecoder.h |
30 |
@@ -23,6 +23,9 @@ |
31 |
extern "C" { |
32 |
#include <libavcodec/avcodec.h> |
33 |
#include <libavformat/avformat.h> |
34 |
+#include <libavfilter/avfilter.h> |
35 |
+#include <libavfilter/buffersrc.h> |
36 |
+#include <libavfilter/buffersink.h> |
37 |
} |
38 |
|
39 |
namespace ffmpegthumbnailer |
40 |
@@ -52,10 +55,14 @@ private: |
41 |
|
42 |
bool decodeVideoPacket(); |
43 |
bool getVideoPacket(); |
44 |
- void convertAndScaleFrame(PixelFormat format, int scaledSize, bool maintainAspectRatio, int& scaledWidth, int& scaledHeight); |
45 |
- void createAVFrame(AVFrame** avFrame, quint8** frameBuffer, int width, int height, PixelFormat format); |
46 |
+ void convertAndScaleFrame(AVPixelFormat format, int scaledSize, bool maintainAspectRatio, int& scaledWidth, int& scaledHeight); |
47 |
+ void createAVFrame(AVFrame** avFrame, quint8** frameBuffer, int width, int height, AVPixelFormat format); |
48 |
void calculateDimensions(int squareSize, bool maintainAspectRatio, int& destWidth, int& destHeight); |
49 |
|
50 |
+ void delete_filter_graph(); |
51 |
+ int init_filter_graph(enum AVPixelFormat pixfmt, int width, int height); |
52 |
+ int process_filter_graph(AVPicture *dst, const AVPicture *src, enum AVPixelFormat pixfmt, int width, int height); |
53 |
+ |
54 |
private: |
55 |
int m_VideoStream; |
56 |
AVFormatContext* m_pFormatContext; |
57 |
@@ -68,6 +75,13 @@ private: |
58 |
bool m_FormatContextWasGiven; |
59 |
bool m_AllowSeek; |
60 |
bool m_initialized; |
61 |
+ AVFilterContext* m_buffersink_ctx; |
62 |
+ AVFilterContext* m_buffersrc_ctx; |
63 |
+ AVFilterGraph* m_filter_graph; |
64 |
+ AVFrame* m_filter_frame; |
65 |
+ int m_last_width; |
66 |
+ int m_last_height; |
67 |
+ enum AVPixelFormat m_last_pixfmt; |
68 |
}; |
69 |
|
70 |
} |
71 |
diff --git a/ffmpegthumbnailer/moviedecoder.cpp b/ffmpegthumbnailer/moviedecoder.cpp |
72 |
index c8ae6d1acd2876cabb5c0594b52f676486be707e..59ae79480575f2394d1f1b7d6dceb5daa7d6e4b7 100644 |
73 |
--- ffmpegthumbnailer/moviedecoder.cpp |
74 |
+++ ffmpegthumbnailer/moviedecoder.cpp |
75 |
@@ -51,6 +51,9 @@ MovieDecoder::~MovieDecoder() |
76 |
|
77 |
void MovieDecoder::initialize(const QString& filename) |
78 |
{ |
79 |
+ m_last_width = -1; |
80 |
+ m_last_height = -1; |
81 |
+ m_last_pixfmt = AV_PIX_FMT_NONE; |
82 |
av_register_all(); |
83 |
avcodec_register_all(); |
84 |
|
85 |
@@ -67,7 +70,7 @@ void MovieDecoder::initialize(const QString& filename) |
86 |
} |
87 |
|
88 |
initializeVideo(); |
89 |
- m_pFrame = avcodec_alloc_frame(); |
90 |
+ m_pFrame = av_frame_alloc(); |
91 |
|
92 |
if (m_pFrame) { |
93 |
m_initialized=true; |
94 |
@@ -82,6 +85,7 @@ bool MovieDecoder::getInitialized() |
95 |
|
96 |
void MovieDecoder::destroy() |
97 |
{ |
98 |
+ delete_filter_graph(); |
99 |
if (m_pVideoCodecContext) { |
100 |
avcodec_close(m_pVideoCodecContext); |
101 |
m_pVideoCodecContext = NULL; |
102 |
@@ -99,7 +103,7 @@ void MovieDecoder::destroy() |
103 |
} |
104 |
|
105 |
if (m_pFrame) { |
106 |
- av_free(m_pFrame); |
107 |
+ av_frame_free(&m_pFrame); |
108 |
m_pFrame = NULL; |
109 |
} |
110 |
|
111 |
@@ -239,7 +243,7 @@ bool MovieDecoder::decodeVideoPacket() |
112 |
return false; |
113 |
} |
114 |
|
115 |
- avcodec_get_frame_defaults(m_pFrame); |
116 |
+ av_frame_unref(m_pFrame); |
117 |
|
118 |
int frameFinished = 0; |
119 |
|
120 |
@@ -283,15 +287,83 @@ bool MovieDecoder::getVideoPacket() |
121 |
return frameDecoded; |
122 |
} |
123 |
|
124 |
+void MovieDecoder::delete_filter_graph() { |
125 |
+ if (m_filter_graph) { |
126 |
+ av_frame_free(&m_filter_frame); |
127 |
+ avfilter_graph_free(&m_filter_graph); |
128 |
+ } |
129 |
+} |
130 |
+ |
131 |
+int MovieDecoder::init_filter_graph(enum AVPixelFormat pixfmt, int width, int height) { |
132 |
+ AVFilterInOut *inputs = NULL, *outputs = NULL; |
133 |
+ char args[512]; |
134 |
+ int res; |
135 |
+ |
136 |
+ delete_filter_graph(); |
137 |
+ m_filter_graph = avfilter_graph_alloc(); |
138 |
+ snprintf(args, sizeof(args), |
139 |
+ "buffer=video_size=%dx%d:pix_fmt=%d:time_base=1/1:pixel_aspect=0/1[in];" |
140 |
+ "[in]yadif[out];" |
141 |
+ "[out]buffersink", |
142 |
+ width, height, pixfmt); |
143 |
+ res = avfilter_graph_parse2(m_filter_graph, args, &inputs, &outputs); |
144 |
+ if (res < 0) |
145 |
+ return res; |
146 |
+ if(inputs || outputs) |
147 |
+ return -1; |
148 |
+ res = avfilter_graph_config(m_filter_graph, NULL); |
149 |
+ if (res < 0) |
150 |
+ return res; |
151 |
+ |
152 |
+ m_buffersrc_ctx = avfilter_graph_get_filter(m_filter_graph, "Parsed_buffer_0"); |
153 |
+ m_buffersink_ctx = avfilter_graph_get_filter(m_filter_graph, "Parsed_buffersink_2"); |
154 |
+ if (!m_buffersrc_ctx || !m_buffersink_ctx) |
155 |
+ return -1; |
156 |
+ m_filter_frame = av_frame_alloc(); |
157 |
+ m_last_width = width; |
158 |
+ m_last_height = height; |
159 |
+ m_last_pixfmt = pixfmt; |
160 |
+ |
161 |
+ return 0; |
162 |
+} |
163 |
+ |
164 |
+int MovieDecoder::process_filter_graph(AVPicture *dst, const AVPicture *src, |
165 |
+ enum AVPixelFormat pixfmt, int width, int height) { |
166 |
+ int res; |
167 |
+ |
168 |
+ if (!m_filter_graph || width != m_last_width || |
169 |
+ height != m_last_height || pixfmt != m_last_pixfmt) { |
170 |
+ res = init_filter_graph(pixfmt, width, height); |
171 |
+ if (res < 0) |
172 |
+ return res; |
173 |
+ } |
174 |
+ |
175 |
+ memcpy(m_filter_frame->data, src->data, sizeof(src->data)); |
176 |
+ memcpy(m_filter_frame->linesize, src->linesize, sizeof(src->linesize)); |
177 |
+ m_filter_frame->width = width; |
178 |
+ m_filter_frame->height = height; |
179 |
+ m_filter_frame->format = pixfmt; |
180 |
+ res = av_buffersrc_add_frame(m_buffersrc_ctx, m_filter_frame); |
181 |
+ if (res < 0) |
182 |
+ return res; |
183 |
+ res = av_buffersink_get_frame(m_buffersink_ctx, m_filter_frame); |
184 |
+ if (res < 0) |
185 |
+ return res; |
186 |
+ av_picture_copy(dst, (const AVPicture *) m_filter_frame, pixfmt, width, height); |
187 |
+ av_frame_unref(m_filter_frame); |
188 |
+ |
189 |
+ return 0; |
190 |
+} |
191 |
+ |
192 |
void MovieDecoder::getScaledVideoFrame(int scaledSize, bool maintainAspectRatio, VideoFrame& videoFrame) |
193 |
{ |
194 |
if (m_pFrame->interlaced_frame) { |
195 |
- avpicture_deinterlace((AVPicture*) m_pFrame, (AVPicture*) m_pFrame, m_pVideoCodecContext->pix_fmt, |
196 |
+ process_filter_graph((AVPicture*) m_pFrame, (AVPicture*) m_pFrame, m_pVideoCodecContext->pix_fmt, |
197 |
m_pVideoCodecContext->width, m_pVideoCodecContext->height); |
198 |
} |
199 |
|
200 |
int scaledWidth, scaledHeight; |
201 |
- convertAndScaleFrame(PIX_FMT_RGB24, scaledSize, maintainAspectRatio, scaledWidth, scaledHeight); |
202 |
+ convertAndScaleFrame(AV_PIX_FMT_RGB24, scaledSize, maintainAspectRatio, scaledWidth, scaledHeight); |
203 |
|
204 |
videoFrame.width = scaledWidth; |
205 |
videoFrame.height = scaledHeight; |
206 |
@@ -302,7 +374,7 @@ void MovieDecoder::getScaledVideoFrame(int scaledSize, bool maintainAspectRatio, |
207 |
memcpy((&(videoFrame.frameData.front())), m_pFrame->data[0], videoFrame.lineSize * videoFrame.height); |
208 |
} |
209 |
|
210 |
-void MovieDecoder::convertAndScaleFrame(PixelFormat format, int scaledSize, bool maintainAspectRatio, int& scaledWidth, int& scaledHeight) |
211 |
+void MovieDecoder::convertAndScaleFrame(AVPixelFormat format, int scaledSize, bool maintainAspectRatio, int& scaledWidth, int& scaledHeight) |
212 |
{ |
213 |
calculateDimensions(scaledSize, maintainAspectRatio, scaledWidth, scaledHeight); |
214 |
SwsContext* scaleContext = sws_getContext(m_pVideoCodecContext->width, m_pVideoCodecContext->height, |
215 |
@@ -323,7 +395,7 @@ void MovieDecoder::convertAndScaleFrame(PixelFormat format, int scaledSize, bool |
216 |
convertedFrame->data, convertedFrame->linesize); |
217 |
sws_freeContext(scaleContext); |
218 |
|
219 |
- av_free(m_pFrame); |
220 |
+ av_frame_free(&m_pFrame); |
221 |
av_free(m_pFrameBuffer); |
222 |
|
223 |
m_pFrame = convertedFrame; |
224 |
@@ -355,9 +427,9 @@ void MovieDecoder::calculateDimensions(int squareSize, bool maintainAspectRatio, |
225 |
} |
226 |
} |
227 |
|
228 |
-void MovieDecoder::createAVFrame(AVFrame** avFrame, quint8** frameBuffer, int width, int height, PixelFormat format) |
229 |
+void MovieDecoder::createAVFrame(AVFrame** avFrame, quint8** frameBuffer, int width, int height, AVPixelFormat format) |
230 |
{ |
231 |
- *avFrame = avcodec_alloc_frame(); |
232 |
+ *avFrame = av_frame_alloc(); |
233 |
|
234 |
int numBytes = avpicture_get_size(format, width, height); |
235 |
*frameBuffer = reinterpret_cast<quint8*>(av_malloc(numBytes)); |
236 |
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt |
237 |
index 1728fcdd14b699b8f4d7e9a9ffcd8ddc11f495c6..b46169a6274af3e75bd303434a6ce82c928875a0 100644 |
238 |
--- tests/CMakeLists.txt |
239 |
+++ tests/CMakeLists.txt |
240 |
@@ -19,7 +19,7 @@ set(ffmpegthumbtest_SRCS ffmpegthumbtest.cpp |
241 |
|
242 |
kde4_add_executable(ffmpegthumbtest ${ffmpegthumbtest_SRCS} ) |
243 |
|
244 |
-target_link_libraries(ffmpegthumbtest ${KDE4_KDECORE_LIBS} ${KDE4_KIO_LIBS} ${AVUTIL_LIBRARIES} ${AVFORMAT_LIBRARIES} ${AVCODEC_LIBRARIES} ${SWSCALE_LIBRARIES}) |
245 |
+target_link_libraries(ffmpegthumbtest ${KDE4_KDECORE_LIBS} ${KDE4_KIO_LIBS} ${AVUTIL_LIBRARIES} ${AVFILTER_LIBRARIES} ${AVFORMAT_LIBRARIES} ${AVCODEC_LIBRARIES} ${SWSCALE_LIBRARIES}) |
246 |
|
247 |
|
248 |
|