AVCodecEncoder: avcodec_close() is deprecated.

A codec context cannot be reopened, anymore.
Reorganize code accordingly.
Remove usage of the AVFormat context (which was not enabled, anyway) since it's no longer possible to do that.
Use av_frame_free() instead of av_free()
This commit is contained in:
JackBurton79
2018-08-16 08:07:21 +02:00
parent 6bbfad51b7
commit 53086e436e
2 changed files with 12 additions and 64 deletions
@@ -43,9 +43,8 @@ AVCodecEncoder::AVCodecEncoder(uint32 codecID, int bitRateScale)
fBitRateScale(bitRateScale), fBitRateScale(bitRateScale),
fCodecID((CodecID)codecID), fCodecID((CodecID)codecID),
fCodec(NULL), fCodec(NULL),
fOwnContext(avcodec_alloc_context3(NULL)), fCodecContext(avcodec_alloc_context3(NULL)),
fCodecContext(fOwnContext), fCodecInitialized(false),
fCodecInitStatus(CODEC_INIT_NEEDED),
fFrame(av_frame_alloc()), fFrame(av_frame_alloc()),
fSwsContext(NULL), fSwsContext(NULL),
fFramesWritten(0) fFramesWritten(0)
@@ -89,8 +88,6 @@ AVCodecEncoder::~AVCodecEncoder()
{ {
TRACE("AVCodecEncoder::~AVCodecEncoder()\n"); TRACE("AVCodecEncoder::~AVCodecEncoder()\n");
_CloseCodecIfNeeded();
if (fSwsContext != NULL) if (fSwsContext != NULL)
sws_freeContext(fSwsContext); sws_freeContext(fSwsContext);
@@ -110,10 +107,10 @@ AVCodecEncoder::~AVCodecEncoder()
fFrame->linesize[1] = 0; fFrame->linesize[1] = 0;
fFrame->linesize[2] = 0; fFrame->linesize[2] = 0;
fFrame->linesize[3] = 0; fFrame->linesize[3] = 0;
av_free(fFrame); av_frame_free(&fFrame);
} }
avcodec_free_context(&fOwnContext); avcodec_free_context(&fCodecContext);
delete[] fChunkBuffer; delete[] fChunkBuffer;
} }
@@ -160,28 +157,9 @@ AVCodecEncoder::SetUp(const media_format* inputFormat)
return B_NO_INIT; return B_NO_INIT;
} }
_CloseCodecIfNeeded();
fInputFormat = *inputFormat; fInputFormat = *inputFormat;
fFramesWritten = 0; fFramesWritten = 0;
const uchar* userData = inputFormat->user_data;
if (*(uint32*)userData == 'ffmp') {
userData += sizeof(uint32);
// The Writer plugin used is the FFmpeg plugin. It stores the
// AVCodecContext pointer in the user data section. Use this
// context instead of our own. It requires the Writer living in
// the same team, of course.
app_info appInfo;
if (be_app->GetAppInfo(&appInfo) == B_OK
&& *(team_id*)userData == appInfo.team) {
userData += sizeof(team_id);
// Use the AVCodecContext from the Writer. This works better
// than using our own context with some encoders.
fCodecContext = *(AVCodecContext**)userData;
}
}
return _Setup(); return _Setup();
} }
@@ -296,8 +274,9 @@ AVCodecEncoder::_Setup()
if (fInputFormat.type == B_MEDIA_RAW_VIDEO) { if (fInputFormat.type == B_MEDIA_RAW_VIDEO) {
TRACE(" B_MEDIA_RAW_VIDEO\n"); TRACE(" B_MEDIA_RAW_VIDEO\n");
// frame rate // frame rate
fCodecContext->time_base.den = (int)fInputFormat.u.raw_video.field_rate; fCodecContext->time_base = (AVRational){1, (int)fInputFormat.u.raw_video.field_rate};
fCodecContext->time_base.num = 1; fCodecContext->framerate = (AVRational){(int)fInputFormat.u.raw_video.field_rate, 1};
// video size // video size
fCodecContext->width = fInputFormat.u.raw_video.display.line_width; fCodecContext->width = fInputFormat.u.raw_video.display.line_width;
fCodecContext->height = fInputFormat.u.raw_video.display.line_count; fCodecContext->height = fInputFormat.u.raw_video.display.line_count;
@@ -486,17 +465,8 @@ AVCodecEncoder::_Setup()
bool bool
AVCodecEncoder::_OpenCodecIfNeeded() AVCodecEncoder::_OpenCodecIfNeeded()
{ {
if (fCodecContext != fOwnContext) { if (fCodecInitialized)
// We are using the AVCodecContext of the AVFormatWriter plugin,
// and don't maintain it's open/close state.
return true; return true;
}
if (fCodecInitStatus == CODEC_INIT_DONE)
return true;
if (fCodecInitStatus == CODEC_INIT_FAILED)
return false;
fCodecContext->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL; fCodecContext->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL;
@@ -508,32 +478,17 @@ AVCodecEncoder::_OpenCodecIfNeeded()
// Open the codec // Open the codec
int result = avcodec_open2(fCodecContext, fCodec, NULL); int result = avcodec_open2(fCodecContext, fCodec, NULL);
if (result >= 0) if (result >= 0)
fCodecInitStatus = CODEC_INIT_DONE; fCodecInitialized = true;
else else
fCodecInitStatus = CODEC_INIT_FAILED; fCodecInitialized = false;
TRACE(" avcodec_open(%p, %p): %d\n", fCodecContext, fCodec, result); TRACE(" avcodec_open(%p, %p): %d\n", fCodecContext, fCodec, result);
return fCodecInitStatus == CODEC_INIT_DONE; return fCodecInitialized;
} }
void
AVCodecEncoder::_CloseCodecIfNeeded()
{
if (fCodecContext != fOwnContext) {
// See _OpenCodecIfNeeded().
return;
}
if (fCodecInitStatus == CODEC_INIT_DONE) {
avcodec_close(fCodecContext);
fCodecInitStatus = CODEC_INIT_NEEDED;
}
}
status_t status_t
AVCodecEncoder::_EncodeAudio(const void* _buffer, int64 frameCount, AVCodecEncoder::_EncodeAudio(const void* _buffer, int64 frameCount,
media_encode_info* info) media_encode_info* info)
@@ -50,7 +50,6 @@ private:
status_t _Setup(); status_t _Setup();
bool _OpenCodecIfNeeded(); bool _OpenCodecIfNeeded();
void _CloseCodecIfNeeded();
status_t _EncodeAudio(const void* buffer, status_t _EncodeAudio(const void* buffer,
int64 frameCount, int64 frameCount,
@@ -75,15 +74,9 @@ private:
// TODO: Refactor common base class from AVCodec[De|En]Coder! // TODO: Refactor common base class from AVCodec[De|En]Coder!
CodecID fCodecID; CodecID fCodecID;
AVCodec* fCodec; AVCodec* fCodec;
AVCodecContext* fOwnContext;
AVCodecContext* fCodecContext; AVCodecContext* fCodecContext;
enum { bool fCodecInitialized;
CODEC_INIT_NEEDED = 0,
CODEC_INIT_DONE,
CODEC_INIT_FAILED
};
uint32 fCodecInitStatus;
// For video (color space conversion): // For video (color space conversion):
AVPicture fSrcFrame; AVPicture fSrcFrame;