53 { |
54 { |
54 static LibavIteraction instance; |
55 static LibavIteraction instance; |
55 return instance; |
56 return instance; |
56 } |
57 } |
57 |
58 |
|
59 // test if given format supports given codec |
58 bool FormatQueryCodec(AVOutputFormat *ofmt, enum CodecID codec_id) |
60 bool FormatQueryCodec(AVOutputFormat *ofmt, enum CodecID codec_id) |
59 { |
61 { |
60 #if LIBAVFORMAT_VERSION_MAJOR >= 54 |
62 #if LIBAVFORMAT_VERSION_MAJOR >= 54 |
61 return avformat_query_codec(ofmt, codec_id, FF_COMPLIANCE_NORMAL) == 1; |
63 return avformat_query_codec(ofmt, codec_id, FF_COMPLIANCE_NORMAL) == 1; |
62 #else |
64 #else |
87 |
89 |
88 if (pCodec->type != AVMEDIA_TYPE_VIDEO && pCodec->type != AVMEDIA_TYPE_AUDIO) |
90 if (pCodec->type != AVMEDIA_TYPE_VIDEO && pCodec->type != AVMEDIA_TYPE_AUDIO) |
89 continue; |
91 continue; |
90 |
92 |
91 // this encoders seems to be buggy |
93 // this encoders seems to be buggy |
92 if (strcmp(pCodec->name, "rv10") == 0 || |
94 if (strcmp(pCodec->name, "rv10") == 0 || strcmp(pCodec->name, "rv20") == 0) |
93 strcmp(pCodec->name, "rv20") == 0) |
|
94 continue; |
95 continue; |
95 |
96 |
96 // doesn't support stereo sound |
97 // doesn't support stereo sound |
97 if (strcmp(pCodec->name, "real_144") == 0) |
98 if (strcmp(pCodec->name, "real_144") == 0) |
98 continue; |
99 continue; |
|
100 |
99 #if LIBAVCODEC_VERSION_MAJOR < 54 |
101 #if LIBAVCODEC_VERSION_MAJOR < 54 |
100 // FIXME: theese doesn't work for some reason |
102 // FIXME: theese doesn't work for some reason |
101 if (strcmp(pCodec->name, "libx264") == 0) |
103 if (strcmp(pCodec->name, "libx264") == 0) |
102 continue; |
104 continue; |
103 if (strcmp(pCodec->name, "libxvid") == 0) |
105 if (strcmp(pCodec->name, "libxvid") == 0) |
192 if (!codec->isAudio) |
194 if (!codec->isAudio) |
193 hasVideoCodec = true; |
195 hasVideoCodec = true; |
194 } |
196 } |
195 if (!hasVideoCodec) |
197 if (!hasVideoCodec) |
196 continue; |
198 continue; |
197 format.shortName = pFormat->name; |
|
198 |
199 |
199 QString ext(pFormat->extensions); |
200 QString ext(pFormat->extensions); |
200 ext.truncate(strcspn(pFormat->extensions, ",")); |
201 ext.truncate(strcspn(pFormat->extensions, ",")); |
|
202 format.extension = ext; |
|
203 format.shortName = pFormat->name; |
201 format.longName = QString("%1 (*.%2)").arg(pFormat->long_name).arg(ext); |
204 format.longName = QString("%1 (*.%2)").arg(pFormat->long_name).arg(ext); |
202 |
205 |
203 // FIXME: remove next line |
206 // FIXME: remove next line |
204 format.longName += QString(" (%1)").arg(format.shortName); |
207 format.longName += QString(" (%1)").arg(format.shortName); |
205 |
208 |
207 |
210 |
208 formats[pFormat->name] = format; |
211 formats[pFormat->name] = format; |
209 } |
212 } |
210 } |
213 } |
211 |
214 |
212 void LibavIteraction::FillFormats(QComboBox * pFormats) |
215 void LibavIteraction::fillFormats(QComboBox * pFormats) |
213 { |
216 { |
214 // first insert recomended formats |
217 // first insert recomended formats |
215 foreach(const Format & format, formats) |
218 foreach(const Format & format, formats) |
216 if (format.isRecomended) |
219 if (format.isRecomended) |
217 pFormats->addItem(format.longName, format.shortName); |
220 pFormats->addItem(format.longName, format.shortName); |
227 // insert separator if necessary |
230 // insert separator if necessary |
228 if (sep != 0 && sep != pFormats->count()) |
231 if (sep != 0 && sep != pFormats->count()) |
229 pFormats->insertSeparator(sep); |
232 pFormats->insertSeparator(sep); |
230 } |
233 } |
231 |
234 |
232 void LibavIteraction::FillCodecs(const QVariant & fmt, QComboBox * pVCodecs, QComboBox * pACodecs) |
235 void LibavIteraction::fillCodecs(const QString & fmt, QComboBox * pVCodecs, QComboBox * pACodecs) |
233 { |
236 { |
234 Format & format = formats[fmt.toString()]; |
237 Format & format = formats[fmt]; |
235 |
238 |
236 // first insert recomended codecs |
239 // first insert recomended codecs |
237 foreach(Codec * codec, format.codecs) |
240 foreach(Codec * codec, format.codecs) |
238 { |
241 { |
239 if (codec->isRecomended) |
242 if (codec->isRecomended) |
265 if (vsep != 0 && vsep != pVCodecs->count()) |
268 if (vsep != 0 && vsep != pVCodecs->count()) |
266 pVCodecs->insertSeparator(vsep); |
269 pVCodecs->insertSeparator(vsep); |
267 if (asep != 0 && asep != pACodecs->count()) |
270 if (asep != 0 && asep != pACodecs->count()) |
268 pACodecs->insertSeparator(asep); |
271 pACodecs->insertSeparator(asep); |
269 } |
272 } |
|
273 |
|
274 QString LibavIteraction::getExtension(const QString & format) |
|
275 { |
|
276 return formats[format].extension; |
|
277 } |
|
278 |
|
279 QString tr(QString a) |
|
280 { |
|
281 return a; |
|
282 } |
|
283 |
|
284 // get information abaout file (duration, resolution etc) in multiline string |
|
285 QString LibavIteraction::getFileInfo(const QString & filepath) |
|
286 { |
|
287 AVFormatContext* pContext = NULL; |
|
288 QByteArray utf8path = filepath.toUtf8(); |
|
289 if (avformat_open_input(&pContext, utf8path.data(), NULL, NULL) < 0) |
|
290 return ""; |
|
291 if (avformat_find_stream_info(pContext, NULL) < 0) |
|
292 return ""; |
|
293 |
|
294 int s = float(pContext->duration)/AV_TIME_BASE; |
|
295 QString desc = QString(tr("Duration: %1m %2s\n")).arg(s/60).arg(s%60); |
|
296 for (int i = 0; i < pContext->nb_streams; i++) |
|
297 { |
|
298 AVStream* pStream = pContext->streams[i]; |
|
299 if (!pStream) |
|
300 continue; |
|
301 AVCodecContext* pCodec = pContext->streams[i]->codec; |
|
302 if (!pCodec) |
|
303 continue; |
|
304 |
|
305 if (pCodec->codec_type == AVMEDIA_TYPE_VIDEO) |
|
306 { |
|
307 desc += QString(tr("Video: %1x%2, ")).arg(pCodec->width).arg(pCodec->height); |
|
308 if (pStream->avg_frame_rate.den) |
|
309 { |
|
310 float fps = float(pStream->avg_frame_rate.num)/pStream->avg_frame_rate.den; |
|
311 desc += QString(tr("%1 fps, ")).arg(fps, 0, 'f', 2); |
|
312 } |
|
313 } |
|
314 else if (pCodec->codec_type == AVMEDIA_TYPE_AUDIO) |
|
315 desc += tr("Audio: "); |
|
316 else |
|
317 continue; |
|
318 AVCodec* pDecoder = avcodec_find_decoder(pCodec->codec_id); |
|
319 desc += pDecoder? pDecoder->name : "unknown"; |
|
320 desc += "\n"; |
|
321 } |
|
322 AVDictionaryEntry* pComment = av_dict_get(pContext->metadata, "comment", NULL, 0); |
|
323 if (pComment) |
|
324 desc += QString("\n") + pComment->value; |
|
325 #if LIBAVCODEC_VERSION_MAJOR < 54 |
|
326 av_close_input_file(pContext); |
|
327 #else |
|
328 avformat_close_input(&pContext); |
|
329 #endif |
|
330 return desc; |
|
331 } |