Permalink
Browse files

HLS/--avf encoder fixes.

- Fix blockiness at stream startup.  Due to the video frames buffered in the
  encoder, the frames we were tagging as keyframes in the output files
  weren't actually the keyframes.
- Simplify profile and level calculations.  If output width is over
  480 pixels or output video bitrate is over 600Kbit, then use Main 3.1,
  otherwise use Baseline 3.0.
- Change default output width and bitrate to 480 and 600Kbit so that
  Baseline 3.0 is used by default.
- Set keyframe distance to 30 for --avf mode.
- Don't look for the MARK_UPDATED_CUT markup when in --avf mode
- Don't clear the seektables when running in --avf mode
  • Loading branch information...
1 parent 8ae3403 commit 8e96e2e4f3e0ae86fdcf03b742ecf82eff905cc9 @cpinkham cpinkham committed Jul 20, 2012
Showing with 17 additions and 23 deletions.
  1. +11 −19 mythtv/libs/libmythtv/avformatwriter.cpp
  2. +6 −4 mythtv/programs/mythtranscode/transcode.cpp
@@ -253,6 +253,7 @@ int AVFormatWriter::WriteVideoFrame(VideoFrame *frame)
uint8_t *planes[3];
int len = frame->size;
unsigned char *buf = frame->buf;
+ int framesEncoded = m_framesWritten + m_bufferedVideoFrameTimes.size();
planes[0] = buf;
planes[1] = planes[0] + frame->width * frame->height;
@@ -265,10 +266,10 @@ int AVFormatWriter::WriteVideoFrame(VideoFrame *frame)
m_picture->linesize[0] = frame->width;
m_picture->linesize[1] = frame->width / 2;
m_picture->linesize[2] = frame->width / 2;
- m_picture->pts = m_framesWritten + 1;
+ m_picture->pts = framesEncoded + 1;
m_picture->type = FF_BUFFER_TYPE_SHARED;
- if ((m_framesWritten % m_keyFrameDist) == 0)
+ if ((framesEncoded % m_keyFrameDist) == 0)
m_picture->pict_type = AV_PICTURE_TYPE_I;
else
m_picture->pict_type = AV_PICTURE_TYPE_NONE;
@@ -301,15 +302,16 @@ int AVFormatWriter::WriteVideoFrame(VideoFrame *frame)
return ret;
}
- if ((m_framesWritten % m_keyFrameDist) == 0)
- m_pkt->flags |= AV_PKT_FLAG_KEY;
-
long long tc = frame->timecode;
if (!m_bufferedVideoFrameTimes.isEmpty())
tc = m_bufferedVideoFrameTimes.takeFirst();
if (!m_bufferedVideoFrameTypes.isEmpty())
- m_bufferedVideoFrameTypes.pop_front();
+ {
+ int pict_type = m_bufferedVideoFrameTypes.takeFirst();
+ if (pict_type == AV_PICTURE_TYPE_I)
+ m_pkt->flags |= AV_PKT_FLAG_KEY;
+ }
if (m_startingTimecodeOffset == -1)
m_startingTimecodeOffset = tc;
@@ -495,27 +497,17 @@ AVStream* AVFormatWriter::AddVideoStream(void)
}
else if (c->codec_id == CODEC_ID_H264)
{
- av_opt_set(c->priv_data, "profile", "baseline", 0);
- if ((c->height <= 240) &&
- (c->width <= 320) &&
- (c->bit_rate <= 768000))
- {
- c->level = 13;
- }
- else if (c->width >= 1024)
- {
- c->level = 41;
- av_opt_set(c->priv_data, "profile", "high", 0);
- }
- else if (c->width >= 960)
+ if ((c->width > 480) ||
+ (c->bit_rate > 600000))
{
c->level = 31;
av_opt_set(c->priv_data, "profile", "main", 0);
}
else
{
c->level = 30;
+ av_opt_set(c->priv_data, "profile", "baseline", 0);
}
c->coder_type = 0;
@@ -726,7 +726,7 @@ Transcode::Transcode(ProgramInfo *pginfo) :
cmdContainer("mpegts"), cmdAudioCodec("aac"),
cmdVideoCodec("libx264"),
cmdWidth(480), cmdHeight(0),
- cmdBitrate(800000), cmdAudioBitrate(64000)
+ cmdBitrate(600000), cmdAudioBitrate(64000)
{
}
@@ -1180,6 +1180,7 @@ int Transcode::TranscodeFile(const QString &inputname,
avfw->SetAudioCodec(cmdAudioCodec);
avfw->SetFilename(outputname);
avfw->SetFramerate(video_frame_rate);
+ avfw->SetKeyFrameDist(30);
}
avfw->SetThreadCount(
@@ -2015,7 +2016,8 @@ int Transcode::TranscodeFile(const QString &inputname,
if (avfw->WriteVideoFrame(&frame) > 0)
{
lastWrittenTime = frame.timecode;
- ++hlsSegmentFrames;
+ if (hls)
+ ++hlsSegmentFrames;
}
}
@@ -2049,7 +2051,7 @@ int Transcode::TranscodeFile(const QString &inputname,
}
if (MythDate::current() > curtime)
{
- if (honorCutList && m_proginfo && !hls &&
+ if (honorCutList && m_proginfo && !avfMode &&
m_proginfo->QueryMarkupFlag(MARK_UPDATED_CUT))
{
LOG(VB_GENERAL, LOG_NOTICE,
@@ -2117,7 +2119,7 @@ int Transcode::TranscodeFile(const QString &inputname,
if (avfw2)
avfw2->CloseFile();
- if (!hls && m_proginfo)
+ if (!avfMode && m_proginfo)
{
m_proginfo->ClearPositionMap(MARK_KEYFRAME);
m_proginfo->ClearPositionMap(MARK_GOP_START);

0 comments on commit 8e96e2e

Please sign in to comment.