MythTV  master
mythavformatwriter.cpp
Go to the documentation of this file.
1 /*
2  * Class AVFormatWriter
3  *
4  * Copyright (C) Chris Pinkham 2011
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 #include "io/mythavformatwriter.h"
21 
22 #include <QtGlobal>
23 #include <QtEndian>
24 
25 // MythTV
29 #include "mythavutil.h"
30 
31 
32 // FFmpeg
33 extern "C" {
34 #include "libavutil/opt.h"
35 #include "libavutil/samplefmt.h"
36 #include "libavutil/imgutils.h"
37 }
38 
39 #define LOC QString("AVFW(%1): ").arg(m_filename)
40 #define LOC_ERR QString("AVFW(%1) Error: ").arg(m_filename)
41 #define LOC_WARN QString("AVFW(%1) Warning: ").arg(m_filename)
42 
44 {
45  if (m_ctx)
46  {
47  av_write_trailer(m_ctx);
48  avio_closep(&m_ctx->pb);
49  for(uint i = 0; i < m_ctx->nb_streams; i++)
50  av_freep(&m_ctx->streams[i]);
51  av_freep(&m_ctx);
52  }
53 
54  av_freep(&m_audioInBuf);
55  av_freep(&m_audioInPBuf);
56  if (m_audPicture)
57  av_frame_free(&m_audPicture);
58  Cleanup();
59  av_frame_free(&m_picture);
60 }
61 
63 {
64  AVOutputFormat *fmt = av_guess_format(m_container.toLatin1().constData(), nullptr, nullptr);
65  if (!fmt)
66  {
67  LOG(VB_RECORD, LOG_ERR, LOC + QString("Init(): Unable to guess AVOutputFormat from container %1")
68  .arg(m_container));
69  return false;
70  }
71 
72  m_fmt = *fmt;
73 
74  if (m_width && m_height)
75  {
76  m_avVideoCodec = avcodec_find_encoder_by_name(m_videoCodec.toLatin1().constData());
77  if (!m_avVideoCodec)
78  {
79  LOG(VB_RECORD, LOG_ERR, LOC + QString("Init(): Unable to find video codec %1")
80  .arg(m_videoCodec));
81  return false;
82  }
83  m_fmt.video_codec = m_avVideoCodec->id;
84  }
85  else
86  {
87  m_fmt.video_codec = AV_CODEC_ID_NONE;
88  }
89 
90  m_avAudioCodec = avcodec_find_encoder_by_name(m_audioCodec.toLatin1().constData());
91  if (!m_avAudioCodec)
92  {
93  LOG(VB_RECORD, LOG_ERR, LOC + QString("Init(): Unable to find audio codec %1")
94  .arg(m_audioCodec));
95  return false;
96  }
97 
98  m_fmt.audio_codec = m_avAudioCodec->id;
99 
100  m_ctx = avformat_alloc_context();
101  if (!m_ctx)
102  {
103  LOG(VB_RECORD, LOG_ERR, LOC + "Init(): Unable to allocate AVFormatContext");
104  return false;
105  }
106 
107  m_ctx->oformat = &m_fmt;
108 
109  if (m_container == "mpegts")
110  m_ctx->packet_size = 2324;
111 
112  QByteArray filename = m_filename.toLatin1();
113  auto size = static_cast<size_t>(filename.size());
114  m_ctx->url = static_cast<char*>(av_malloc(size));
115  memcpy(m_ctx->url, filename.constData(), size);
116 
117  if (m_fmt.video_codec != AV_CODEC_ID_NONE)
119  if (m_fmt.audio_codec != AV_CODEC_ID_NONE)
121 
122  if (m_videoStream && !OpenVideo())
123  {
124  LOG(VB_RECORD, LOG_ERR, LOC + "Init(): OpenVideo() failed");
125  return false;
126  }
127 
128  if (m_audioStream && !OpenAudio())
129  {
130  LOG(VB_RECORD, LOG_ERR, LOC + "Init(): OpenAudio() failed");
131  return false;
132  }
133 
134  return true;
135 }
136 
138 {
139  if (!(m_fmt.flags & AVFMT_NOFILE))
140  {
141  if (avio_open(&m_ctx->pb, m_filename.toLatin1().constData(), AVIO_FLAG_WRITE) < 0)
142  {
143  LOG(VB_RECORD, LOG_ERR, LOC + "OpenFile(): avio_open() failed");
144  return false;
145  }
146  }
147 
149 
150  if (!m_buffer || !m_buffer->GetLastError().isEmpty())
151  {
152  LOG(VB_RECORD, LOG_ERR, LOC + QString("OpenFile(): RingBuffer::Create() failed: '%1'")
153  .arg(m_buffer ? m_buffer->GetLastError() : ""));
154  Cleanup();
155  return false;
156  }
157 
159  auto *url = reinterpret_cast<URLContext*>(m_ctx->pb->opaque);
161  url->priv_data = static_cast<void*>(m_avfBuffer);
162 
163  if (avformat_write_header(m_ctx, nullptr) < 0)
164  {
165  Cleanup();
166  return false;
167  }
168 
169  return true;
170 }
171 
173 {
174  if (m_ctx && m_ctx->pb)
175  avio_closep(&m_ctx->pb);
176  delete m_avfBuffer;
177  m_avfBuffer = nullptr;
178  delete m_buffer;
179  m_buffer = nullptr;
180 }
181 
183 {
184  if (m_ctx)
185  {
186  av_write_trailer(m_ctx);
187  avio_close(m_ctx->pb);
188  for(uint i = 0; i < m_ctx->nb_streams; i++)
189  av_freep(&m_ctx->streams[i]);
190  av_freep(&m_ctx);
191  }
192  return true;
193 }
194 
196 {
197  return (m_bufferedVideoFrameTypes.isEmpty()) ||
198  (m_bufferedVideoFrameTypes.first() == AV_PICTURE_TYPE_I);
199 }
200 
202 {
203  long long framesEncoded = m_framesWritten + m_bufferedVideoFrameTimes.size();
204 
205  av_frame_unref(m_picture);
207  m_picture->pts = framesEncoded + 1;
208  m_picture->pict_type = ((framesEncoded % m_keyFrameDist) == 0) ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_NONE;
209 
210  m_bufferedVideoFrameTimes.push_back(Frame->m_timecode);
211  m_bufferedVideoFrameTypes.push_back(m_picture->pict_type);
212 
213  AVPacket *pkt = av_packet_alloc();
214  if (pkt == nullptr)
215  {
216  LOG(VB_RECORD, LOG_ERR, "packet allocation failed");
217  return AVERROR(ENOMEM);
218  }
219 
220  int got_pkt = 0;
221  AVCodecContext *avctx = m_codecMap.GetCodecContext(m_videoStream);
222  int ret = avcodec_encode_video2(avctx, pkt, m_picture, &got_pkt);
223 
224  if (ret < 0)
225  {
226  LOG(VB_RECORD, LOG_ERR, "avcodec_encode_video2() failed");
227  av_packet_free(&pkt);
228  return ret;
229  }
230 
231  if (!got_pkt)
232  {
233  av_packet_free(&pkt);
234  return ret;
235  }
236 
237  std::chrono::milliseconds tc = Frame->m_timecode;
238 
239  if (!m_bufferedVideoFrameTimes.isEmpty())
240  tc = m_bufferedVideoFrameTimes.takeFirst();
241 
242  if (!m_bufferedVideoFrameTypes.isEmpty())
243  {
244  int pict_type = m_bufferedVideoFrameTypes.takeFirst();
245  if (pict_type == AV_PICTURE_TYPE_I)
246  pkt->flags |= AV_PKT_FLAG_KEY;
247  }
248 
249  if (m_startingTimecodeOffset == -1ms)
250  m_startingTimecodeOffset = tc - 1ms;
252 
253  pkt->pts = tc.count() * m_videoStream->time_base.den / m_videoStream->time_base.num / 1000;
254  pkt->dts = AV_NOPTS_VALUE;
255  pkt->stream_index= m_videoStream->index;
256 
257  ret = av_interleaved_write_frame(m_ctx, pkt);
258  if (ret != 0)
259  LOG(VB_RECORD, LOG_ERR, LOC + "WriteVideoFrame(): av_interleaved_write_frame couldn't write Video");
260 
261  Frame->m_timecode = tc + m_startingTimecodeOffset;
262  m_framesWritten++;
263  av_packet_unref(pkt);
264  av_packet_free(&pkt);
265  return 1;
266 }
267 
268 int MythAVFormatWriter::WriteAudioFrame(unsigned char *Buffer, int /*FrameNumber*/, std::chrono::milliseconds &Timecode)
269 {
270 #if (Q_BYTE_ORDER == Q_BIG_ENDIAN)
271  auto buf16 = reinterpret_cast<uint16_t *>(Buffer);
272  for (int i = 0; i < m_audioChannels * m_audioFrameSize; i++)
273  buf16[i] = qFromLittleEndian<quint16>(buf16[i]);
274 #endif
275 
276  AVCodecContext *avctx = m_codecMap.GetCodecContext(m_audioStream);
277  int samples_per_avframe = m_audioFrameSize * m_audioChannels;
278  int sampleSizeIn = AudioOutputSettings::SampleSize(FORMAT_S16);
279  AudioFormat format = AudioOutputSettings::AVSampleFormatToFormat(avctx->sample_fmt);
280  int sampleSizeOut = AudioOutputSettings::SampleSize(format);
281 
282  AVPacket *pkt = av_packet_alloc();
283  if (pkt == nullptr)
284  {
285  LOG(VB_RECORD, LOG_ERR, "packet allocation failed");
286  return AVERROR(ENOMEM);
287  }
288 
289  if (av_get_packed_sample_fmt(avctx->sample_fmt) == AV_SAMPLE_FMT_FLT)
290  {
291  AudioOutputUtil::toFloat(FORMAT_S16, static_cast<void*>(m_audioInBuf),
292  static_cast<void*>(Buffer), samples_per_avframe * sampleSizeIn);
294  }
295  if (av_sample_fmt_is_planar(avctx->sample_fmt))
296  {
299  samples_per_avframe * sampleSizeOut);
300 
301  // init AVFrame for planar data (input is interleaved)
302  for (int j = 0, jj = 0; j < m_audioChannels; j++, jj += m_audioFrameSize)
303  m_audPicture->data[j] = m_audioInPBuf + jj * sampleSizeOut;
304  }
305  else
306  {
307  m_audPicture->data[0] = Buffer;
308  }
309 
310  m_audPicture->linesize[0] = m_audioFrameSize;
311  m_audPicture->nb_samples = m_audioFrameSize;
312  m_audPicture->format = avctx->sample_fmt;
313  m_audPicture->extended_data = m_audPicture->data;
314  m_bufferedAudioFrameTimes.push_back(Timecode);
315 
316  // SUGGESTION
317  // Now that avcodec_encode_audio2 is deprecated and replaced
318  // by 2 calls, this could be optimized
319  // into separate routines or separate threads.
320  bool got_packet = false;
321  int ret = avcodec_receive_packet(avctx, pkt);
322  if (ret == 0)
323  got_packet = true;
324  if (ret == AVERROR(EAGAIN))
325  ret = 0;
326  if (ret == 0)
327  ret = avcodec_send_frame(avctx, m_audPicture);
328  // if ret from avcodec_send_frame is AVERROR(EAGAIN) then
329  // there are 2 packets to be received while only 1 frame to be
330  // sent. The code does not cater for this. Hopefully it will not happen.
331 
332  if (ret < 0)
333  {
334  std::string error;
335  LOG(VB_GENERAL, LOG_ERR, LOC + QString("audio encode error: %1 (%2)")
336  .arg(av_make_error_stdstring(error, ret)).arg(got_packet));
337  av_packet_free(&pkt);
338  return ret;
339  }
340 
341  if (!got_packet)
342  {
343  av_packet_free(&pkt);
344  return ret;
345  }
346 
347  std::chrono::milliseconds tc = Timecode;
348 
349  if (!m_bufferedAudioFrameTimes.empty())
350  tc = m_bufferedAudioFrameTimes.takeFirst();
351 
352  if (m_startingTimecodeOffset == -1ms)
353  m_startingTimecodeOffset = tc - 1ms;
355 
356  if (m_avVideoCodec)
357  pkt->pts = tc.count() * m_videoStream->time_base.den / m_videoStream->time_base.num / 1000;
358  else
359  pkt->pts = tc.count() * m_audioStream->time_base.den / m_audioStream->time_base.num / 1000;
360 
361  pkt->dts = AV_NOPTS_VALUE;
362  pkt->flags |= AV_PKT_FLAG_KEY;
363  pkt->stream_index = m_audioStream->index;
364 
365  ret = av_interleaved_write_frame(m_ctx, pkt);
366  if (ret != 0)
367  LOG(VB_RECORD, LOG_ERR, LOC + "WriteAudioFrame(): av_interleaved_write_frame couldn't write Audio");
368 
369  Timecode = tc + m_startingTimecodeOffset;
370  av_packet_unref(pkt);
371  av_packet_free(&pkt);
372  return 1;
373 }
374 
375 int MythAVFormatWriter::WriteTextFrame(int /*VBIMode*/, unsigned char* /*Buffer*/, int /*Length*/,
376  std::chrono::milliseconds /*Timecode*/, int /*PageNumber*/)
377 {
378  return 1;
379 }
380 
382 {
383  return 1;
384 }
385 
387 {
388  return false;
389 }
390 
391 bool MythAVFormatWriter::ReOpen(const QString& Filename)
392 {
393  bool result = m_buffer->ReOpen(Filename);
394  if (result)
395  m_filename = Filename;
396  return result;
397 }
398 
400 {
401  AVStream *stream = avformat_new_stream(m_ctx, nullptr);
402  if (!stream)
403  {
404  LOG(VB_RECORD, LOG_ERR, LOC + "AddVideoStream(): avformat_new_stream() failed");
405  return nullptr;
406  }
407 
408  stream->id = 0;
409  stream->time_base.den = 90000;
410  stream->time_base.num = 1;
411  stream->r_frame_rate.num = 0;
412  stream->r_frame_rate.den = 0;
413 
414  AVCodec *codec = avcodec_find_encoder(m_ctx->oformat->video_codec);
415  if (!codec)
416  {
417  LOG(VB_RECORD, LOG_ERR, LOC + "AddVideoStream(): avcodec_find_encoder() failed");
418  return nullptr;
419  }
420 
422  AVCodecContext *context = m_codecMap.GetCodecContext(stream, codec);
423  context->codec = codec;
424  context->codec_id = m_ctx->oformat->video_codec;
425  context->codec_type = AVMEDIA_TYPE_VIDEO;
426  context->bit_rate = m_videoBitrate;
427  context->width = m_width;
428  context->height = m_height;
429 
430  // c->sample_aspect_ratio.num = (int)floor(m_aspect * 10000);
431  // c->sample_aspect_ratio.den = 10000;
432 
433  context->time_base = GetCodecTimeBase();
434  context->gop_size = m_keyFrameDist;
435  context->pix_fmt = AV_PIX_FMT_YUV420P;
436  context->thread_count = m_encodingThreadCount;
437  context->thread_type = FF_THREAD_SLICE;
438 
439  if (context->codec_id == AV_CODEC_ID_MPEG2VIDEO)
440  {
441  context->max_b_frames = 2;
442  }
443  else if (context->codec_id == AV_CODEC_ID_MPEG1VIDEO)
444  {
445  context->mb_decision = 2;
446  }
447  else if (context->codec_id == AV_CODEC_ID_H264)
448  {
449 
450  // Try to provide the widest software/device support by automatically using
451  // the Baseline profile where the given bitrate and resolution permits
452 
453  if ((context->height > 720) || // Approximate highest resolution supported by Baseline 3.1
454  (context->bit_rate > 1400000)) // 14,000 Kbps aka 14Mbps maximum permissable rate for Baseline 3.1
455  {
456  context->level = 40;
457  // AVCodecContext AVOptions:
458  av_opt_set(context->priv_data, "profile", "main", 0);
459  }
460  else if ((context->height > 576) || // Approximate highest resolution supported by Baseline 3.0
461  (context->bit_rate > 1000000)) // 10,000 Kbps aka 10Mbps maximum permissable rate for Baseline 3.0
462  {
463  context->level = 31;
464  // AVCodecContext AVOptions:
465  av_opt_set(context->priv_data, "profile", "baseline", 0);
466  }
467  else
468  {
469  context->level = 30; // Baseline 3.0 is the most widely supported, but it's limited to SD
470  // AVCodecContext AVOptions:
471  av_opt_set(context->priv_data, "profile", "baseline", 0);
472  }
473 
474  // AVCodecContext AVOptions:
475  // c->coder_type = 0;
476  av_opt_set_int(context, "coder", FF_CODER_TYPE_VLC, 0);
477  context->max_b_frames = 0;
478  context->slices = 8;
479  context->flags |= AV_CODEC_FLAG_LOOP_FILTER;
480  context->me_cmp |= 1;
481  // c->me_method = ME_HEX;
482  // av_opt_set_int(c, "me_method", ME_HEX, 0);
483  av_opt_set(context, "me_method", "hex", 0);
484  context->me_subpel_quality = 6;
485  context->me_range = 16;
486  context->keyint_min = 25;
487  // c->scenechange_threshold = 40;
488  av_opt_set_int(context, "sc_threshold", 40, 0);
489  context->i_quant_factor = 0.71F;
490  // c->b_frame_strategy = 1;
491  av_opt_set_int(context, "b_strategy", 1, 0);
492  context->qcompress = 0.6F;
493  context->qmin = 10;
494  context->qmax = 51;
495  context->max_qdiff = 4;
496  context->refs = 3;
497  context->trellis = 0;
498 
499  // libx264 AVOptions:
500  av_opt_set(context, "partitions", "i8x8,i4x4,p8x8,b8x8", 0);
501  av_opt_set_int(context, "direct-pred", 1, 0);
502  av_opt_set_int(context, "rc-lookahead", 0, 0);
503  av_opt_set_int(context, "fast-pskip", 1, 0);
504  av_opt_set_int(context, "mixed-refs", 1, 0);
505  av_opt_set_int(context, "8x8dct", 0, 0);
506  av_opt_set_int(context, "weightb", 0, 0);
507 
508  // libx264 AVOptions:
509  av_opt_set(context->priv_data, "preset", m_encodingPreset.toLatin1().constData(), 0);
510  av_opt_set(context->priv_data, "tune", m_encodingTune.toLatin1().constData(), 0);
511  }
512 
513  if(m_ctx->oformat->flags & AVFMT_GLOBALHEADER)
514  context->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
515 
516  return stream;
517 }
518 
520 {
521  if (!m_width || !m_height)
522  return false;
523 
524  AVCodecContext *context = m_codecMap.GetCodecContext(m_videoStream);
525  if (avcodec_open2(context, nullptr, nullptr) < 0)
526  {
527  LOG(VB_RECORD, LOG_ERR, LOC + "OpenVideo(): avcodec_open() failed");
528  return false;
529  }
530 
531  if (!m_picture)
532  {
533  m_picture = AllocPicture(context->pix_fmt);
534  if (!m_picture)
535  {
536  LOG(VB_RECORD, LOG_ERR, LOC + "OpenVideo(): AllocPicture() failed");
537  return false;
538  }
539  }
540  else
541  {
542  av_frame_unref(m_picture);
543  }
544 
545  return true;
546 }
547 
549 {
550  AVStream *stream = avformat_new_stream(m_ctx, nullptr);
551  if (!stream)
552  {
553  LOG(VB_RECORD, LOG_ERR, LOC + "AddAudioStream(): avformat_new_stream() failed");
554  return nullptr;
555  }
556  stream->id = 1;
557 
558  AVCodecContext *context = m_codecMap.GetCodecContext(stream, nullptr, true);
559 
560  context->codec_id = m_ctx->oformat->audio_codec;
561  context->codec_type = AVMEDIA_TYPE_AUDIO;
562  context->bit_rate = m_audioBitrate;
563  context->sample_rate = m_audioFrameRate;
564  context->channels = m_audioChannels;
565  context->channel_layout = static_cast<uint64_t>(av_get_default_channel_layout(m_audioChannels));
566 
567  // c->flags |= CODEC_FLAG_QSCALE; // VBR
568  // c->global_quality = blah;
569 
570  if (!m_avVideoCodec)
571  {
572  context->time_base = GetCodecTimeBase();
573  stream->time_base.den = 90000;
574  stream->time_base.num = 1;
575  }
576 
577  if (m_ctx->oformat->flags & AVFMT_GLOBALHEADER)
578  context->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
579 
580  return stream;
581 }
582 
583 bool MythAVFormatWriter::FindAudioFormat(AVCodecContext *Ctx, AVCodec *Codec, AVSampleFormat Format)
584 {
585  if (Codec->sample_fmts)
586  {
587  for (int i = 0; Codec->sample_fmts[i] != AV_SAMPLE_FMT_NONE; i++)
588  {
589  if (av_get_packed_sample_fmt(Codec->sample_fmts[i]) == Format)
590  {
591  Ctx->sample_fmt = Codec->sample_fmts[i];
592  return true;
593  }
594  }
595  }
596  return false;
597 }
598 
600 {
601  AVCodecContext *context = m_codecMap.GetCodecContext(m_audioStream);
602  context->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL;
603 
604  AVCodec *codec = avcodec_find_encoder(context->codec_id);
605  if (!codec)
606  {
607  LOG(VB_RECORD, LOG_ERR, LOC + "OpenAudio(): avcodec_find_encoder() failed");
608  return false;
609  }
610 
611  // try to find suitable format we can use. avcodec_open2 will fail if we don't
612  // find one, so no need to worry otherwise. Can only handle S16 or FLOAT
613  // we give priority to S16 as libmp3lame requires aligned floats which we can't guarantee
614  if (!FindAudioFormat(context, codec, AV_SAMPLE_FMT_S16))
615  FindAudioFormat(context, codec, AV_SAMPLE_FMT_FLT);
616 
617  if (avcodec_open2(context, codec, nullptr) < 0)
618  {
619  LOG(VB_RECORD, LOG_ERR, LOC + "OpenAudio(): avcodec_open() failed");
620  return false;
621  }
622 
623  m_audioFrameSize = context->frame_size; // number of *samples* per channel in an AVFrame
624 
625  m_audPicture = av_frame_alloc();
626  if (!m_audPicture)
627  {
628  LOG(VB_RECORD, LOG_ERR, LOC + "OpenAudio(): alloc_frame() failed");
629  return false;
630  }
631 
632  auto size = static_cast<size_t>(m_audioFrameSize * m_audioChannels *
633  av_get_bytes_per_sample(context->sample_fmt));
634  if (av_get_packed_sample_fmt(context->sample_fmt) == AV_SAMPLE_FMT_FLT)
635  {
636  // allocate buffer to convert from S16 to float
637  if (!(m_audioInBuf = static_cast<unsigned char*>(av_malloc(size))))
638  return false;
639  }
640 
641  if (av_sample_fmt_is_planar(context->sample_fmt))
642  {
643  // allocate buffer to convert interleaved to planar audio
644  if (!(m_audioInPBuf = static_cast<unsigned char*>(av_malloc(size))))
645  return false;
646  }
647  return true;
648 }
649 
650 AVFrame* MythAVFormatWriter::AllocPicture(enum AVPixelFormat PixFmt)
651 {
652  AVFrame *picture = av_frame_alloc();
653  if (!picture)
654  {
655  LOG(VB_RECORD, LOG_ERR, LOC + "AllocPicture failed");
656  return nullptr;
657  }
658 
659  int size = av_image_get_buffer_size(PixFmt, m_width, m_height, IMAGE_ALIGN);
660  auto *buffer = static_cast<unsigned char*>(av_malloc(static_cast<size_t>(size)));
661  if (!buffer)
662  {
663  LOG(VB_RECORD, LOG_ERR, LOC + "AllocPicture(): av_malloc() failed");
664  av_frame_free(&picture);
665  return nullptr;
666  }
667 
668  av_image_fill_arrays(picture->data, picture->linesize, buffer, PixFmt, m_width, m_height, IMAGE_ALIGN);
669  return picture;
670 }
671 
673 {
674  AVRational result;
675  result.den = static_cast<int>(floor(m_frameRate * 100));
676  result.num = 100;
677 
678  if (m_avVideoCodec && m_avVideoCodec->supported_framerates)
679  {
680  const AVRational *rates = m_avVideoCodec->supported_framerates;
681  AVRational req = { result.den, result.num };
682  const AVRational *best = nullptr;
683  AVRational best_error= { INT_MAX, 1 };
684  for (; rates->den != 0; rates++)
685  {
686  AVRational error = av_sub_q(req, *rates);
687  if (error.num < 0)
688  error.num *= -1;
689  if (av_cmp_q(error, best_error) < 0)
690  {
691  best_error = error;
692  best = rates;
693  }
694  }
695 
696  if (best && best->num && best->den)
697  {
698  result.den = best->num;
699  result.num = best->den;
700  }
701  }
702 
703  if (result.den == 2997)
704  {
705  result.den = 30000;
706  result.num = 1001;
707  }
708  else if (result.den == 5994)
709  {
710  result.den = 60000;
711  result.num = 1001;
712  }
713 
714  return result;
715 }
MythMediaWriter::m_audioChannels
int m_audioChannels
Definition: mythmediawriter.h:62
MythMediaWriter::m_audioBitrate
int m_audioBitrate
Definition: mythmediawriter.h:61
MythAVFormatWriter::m_fmt
AVOutputFormat m_fmt
Definition: mythavformatwriter.h:50
AudioOutputSettings::AVSampleFormatToFormat
static AudioFormat AVSampleFormatToFormat(AVSampleFormat format, int bits=0)
Return AVSampleFormat closest equivalent to AudioFormat.
Definition: audiooutputsettings.cpp:198
MythMediaWriter::m_videoCodec
QString m_videoCodec
Definition: mythmediawriter.h:53
MythAVFormatWriter::OpenVideo
bool OpenVideo(void)
Definition: mythavformatwriter.cpp:519
error
static void error(const char *str,...)
Definition: vbi.cpp:35
FORMAT_S16
@ FORMAT_S16
Definition: audiooutputsettings.h:27
MythCodecMap::GetCodecContext
AVCodecContext * GetCodecContext(const AVStream *Stream, const AVCodec *Codec=nullptr, bool NullCodec=false)
Definition: mythavutil.cpp:255
MythAVFormatWriter::GetCodecTimeBase
AVRational GetCodecTimeBase(void)
Definition: mythavformatwriter.cpp:672
MythAVFormatWriter::ReOpen
bool ReOpen(const QString &Filename)
Definition: mythavformatwriter.cpp:391
MythAVFormatWriter::~MythAVFormatWriter
~MythAVFormatWriter() override
Definition: mythavformatwriter.cpp:43
audiooutpututil.h
MythAVFormatWriter::m_avfBuffer
MythAVFormatBuffer * m_avfBuffer
Definition: mythavformatwriter.h:48
MythMediaBuffer::ReOpen
virtual bool ReOpen(const QString &="")
Definition: mythmediabuffer.h:136
MythAVFormatWriter::WriteSeekTable
int WriteSeekTable(void) override
Definition: mythavformatwriter.cpp:381
AudioOutputUtil::toFloat
static int toFloat(AudioFormat format, void *out, const void *in, int bytes)
Convert integer samples to floats.
Definition: audiooutpututil.cpp:71
MythAVFormatWriter::SwitchToNextFile
bool SwitchToNextFile(void) override
Definition: mythavformatwriter.cpp:386
Frame
Definition: zmdefines.h:93
MythMediaWriter::m_container
QString m_container
Definition: mythmediawriter.h:52
MythMediaWriter::m_height
int m_height
Definition: mythmediawriter.h:56
AudioOutputSettings::SampleSize
static int SampleSize(AudioFormat format)
Definition: audiooutputsettings.cpp:180
MythAVFormatWriter::AddVideoStream
AVStream * AddVideoStream(void)
Definition: mythavformatwriter.cpp:399
MythMediaWriter::m_videoBitrate
int m_videoBitrate
Definition: mythmediawriter.h:54
MythDate::Format
Format
Definition: mythdate.h:15
MythAVFormatWriter::m_avAudioCodec
AVCodec * m_avAudioCodec
Definition: mythavformatwriter.h:56
MythMediaWriter::m_keyFrameDist
int m_keyFrameDist
Definition: mythmediawriter.h:59
MythAVFormatWriter::m_ctx
AVFormatContext * m_ctx
Definition: mythavformatwriter.h:51
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:23
MythMediaWriter::m_audioFrameSize
int m_audioFrameSize
Definition: mythmediawriter.h:65
MythMediaWriter::m_encodingThreadCount
int m_encodingThreadCount
Definition: mythmediawriter.h:66
MythAVFormatWriter::m_audioStream
AVStream * m_audioStream
Definition: mythavformatwriter.h:55
MythAVFormatWriter::m_videoStream
AVStream * m_videoStream
Definition: mythavformatwriter.h:53
MythAVFormatWriter::m_codecMap
MythCodecMap m_codecMap
Definition: mythavformatwriter.h:52
MythAVFormatWriter::m_avVideoCodec
AVCodec * m_avVideoCodec
Definition: mythavformatwriter.h:54
MythAVFormatWriter::m_bufferedVideoFrameTypes
QList< int > m_bufferedVideoFrameTypes
Definition: mythavformatwriter.h:62
MythAVFormatWriter::m_buffer
MythMediaBuffer * m_buffer
Definition: mythavformatwriter.h:49
MythMediaWriter::m_audioCodec
QString m_audioCodec
Definition: mythmediawriter.h:60
MythMediaWriter::m_startingTimecodeOffset
std::chrono::milliseconds m_startingTimecodeOffset
Definition: mythmediawriter.h:68
AVFrame
struct AVFrame AVFrame
Definition: BorderDetector.h:15
LOC
#define LOC
Definition: mythavformatwriter.cpp:39
mythlogging.h
MythAVFormatWriter::OpenFile
bool OpenFile(void) override
Definition: mythavformatwriter.cpp:137
MythMediaWriter::m_encodingPreset
QString m_encodingPreset
Definition: mythmediawriter.h:69
MythAVFormatWriter::NextFrameIsKeyFrame
bool NextFrameIsKeyFrame(void)
Definition: mythavformatwriter.cpp:195
MythAVFormatWriter::m_picture
AVFrame * m_picture
Definition: mythavformatwriter.h:57
MythCodecMap::FreeCodecContext
void FreeCodecContext(const AVStream *Stream)
Definition: mythavutil.cpp:303
MythAVFormatWriter::m_audioInPBuf
unsigned char * m_audioInPBuf
Definition: mythavformatwriter.h:60
MythMediaWriter::m_audioFrameRate
int m_audioFrameRate
Definition: mythmediawriter.h:63
MythAVFormatBuffer::GetURLProtocol
static URLProtocol * GetURLProtocol(void)
Definition: mythavformatbuffer.cpp:91
MythAVFormatWriter::CloseFile
bool CloseFile(void) override
Definition: mythavformatwriter.cpp:182
MythAVFormatWriter::OpenAudio
bool OpenAudio(void)
Definition: mythavformatwriter.cpp:599
mythavformatwriter.h
uint
unsigned int uint
Definition: compat.h:79
MythAVFormatWriter::WriteVideoFrame
int WriteVideoFrame(MythVideoFrame *Frame) override
Definition: mythavformatwriter.cpp:201
MythAVFormatWriter::FindAudioFormat
static bool FindAudioFormat(AVCodecContext *Ctx, AVCodec *Codec, AVSampleFormat Format)
Definition: mythavformatwriter.cpp:583
MythAVFormatWriter::m_audioInBuf
unsigned char * m_audioInBuf
Definition: mythavformatwriter.h:59
Buffer
Definition: MythExternControl.h:36
MythAVFormatWriter::m_bufferedVideoFrameTimes
QList< std::chrono::milliseconds > m_bufferedVideoFrameTimes
Definition: mythavformatwriter.h:61
MythMediaWriter::m_encodingTune
QString m_encodingTune
Definition: mythmediawriter.h:70
mythcorecontext.h
MythMediaWriter::m_width
int m_width
Definition: mythmediawriter.h:55
mythavutil.h
MythAVFormatWriter::m_bufferedAudioFrameTimes
QList< std::chrono::milliseconds > m_bufferedAudioFrameTimes
Definition: mythavformatwriter.h:63
MythAVFormatWriter::Cleanup
void Cleanup(void)
Definition: mythavformatwriter.cpp:172
MythMediaBuffer::Create
static MythMediaBuffer * Create(const QString &Filename, bool Write, bool UseReadAhead=true, std::chrono::milliseconds Timeout=kDefaultOpenTimeout, bool StreamOnly=false)
Creates a RingBuffer instance.
Definition: mythmediabuffer.cpp:98
MythMediaBuffer::GetLastError
QString GetLastError(void) const
Definition: mythmediabuffer.cpp:1761
MythAVFormatWriter::AddAudioStream
AVStream * AddAudioStream(void)
Definition: mythavformatwriter.cpp:548
MythAVFormatWriter::AllocPicture
AVFrame * AllocPicture(enum AVPixelFormat PixFmt)
Definition: mythavformatwriter.cpp:650
MythAVFormatWriter::m_audPicture
AVFrame * m_audPicture
Definition: mythavformatwriter.h:58
AudioOutputUtil::DeinterleaveSamples
static void DeinterleaveSamples(AudioFormat format, int channels, uint8_t *output, const uint8_t *input, int data_size)
Deinterleave input samples Deinterleave audio samples and compact them.
Definition: audiooutpututil.cpp:307
uint16_t
unsigned short uint16_t
Definition: iso6937tables.h:3
MythMediaWriter::m_filename
QString m_filename
Definition: mythmediawriter.h:51
MythVideoFrame
Definition: mythframe.h:88
AudioFormat
AudioFormat
Definition: audiooutputsettings.h:24
MythAVFormatBuffer
Definition: mythavformatbuffer.h:13
build_compdb.filename
filename
Definition: build_compdb.py:21
MythMediaWriter::m_framesWritten
long long m_framesWritten
Definition: mythmediawriter.h:67
MythAVUtil::FillAVFrame
static int FillAVFrame(AVFrame *Frame, const MythVideoFrame *From, AVPixelFormat Fmt=AV_PIX_FMT_NONE)
Initialise AVFrame with content from MythVideoFrame.
Definition: mythavutil.cpp:166
MythAVFormatWriter::Init
bool Init(void) override
Definition: mythavformatwriter.cpp:62
av_make_error_stdstring
char * av_make_error_stdstring(std::string &errbuf, int errnum)
Definition: mythaverror.cpp:41
MythAVFormatWriter::WriteTextFrame
int WriteTextFrame(int VBIMode, unsigned char *Buffer, int Length, std::chrono::milliseconds Timecode, int PageNumber) override
Definition: mythavformatwriter.cpp:375
MythAVFormatWriter::WriteAudioFrame
int WriteAudioFrame(unsigned char *Buffer, int FrameNumber, std::chrono::milliseconds &Timecode) override
Definition: mythavformatwriter.cpp:268
MythMediaWriter::m_frameRate
double m_frameRate
Definition: mythmediawriter.h:58