lavc: add avcodec_encode_video2() that encodes from an AVFrame -> AVPacket
Deprecate avcodec_encode_video().
This commit is contained in:
parent
21d0d1d64f
commit
52f82a1148
@ -13,6 +13,9 @@ libavutil: 2011-04-18
|
|||||||
|
|
||||||
API changes, most recent first:
|
API changes, most recent first:
|
||||||
|
|
||||||
|
2012-02-01 - xxxxxxx - lavc 54.01.0
|
||||||
|
Add avcodec_encode_video2() and deprecate avcodec_encode_video().
|
||||||
|
|
||||||
2012-02-01 - 316fc74 - lavc 54.01.0
|
2012-02-01 - 316fc74 - lavc 54.01.0
|
||||||
Add av_fast_padded_malloc() as alternative for av_realloc() when aligned
|
Add av_fast_padded_malloc() as alternative for av_realloc() when aligned
|
||||||
memory is required. The buffer will always have FF_INPUT_BUFFER_PADDING_SIZE
|
memory is required. The buffer will always have FF_INPUT_BUFFER_PADDING_SIZE
|
||||||
|
@ -3770,7 +3770,10 @@ int avcodec_fill_audio_frame(AVFrame *frame, int nb_channels,
|
|||||||
enum AVSampleFormat sample_fmt, const uint8_t *buf,
|
enum AVSampleFormat sample_fmt, const uint8_t *buf,
|
||||||
int buf_size, int align);
|
int buf_size, int align);
|
||||||
|
|
||||||
|
#if FF_API_OLD_ENCODE_VIDEO
|
||||||
/**
|
/**
|
||||||
|
* @deprecated use avcodec_encode_video2() instead.
|
||||||
|
*
|
||||||
* Encode a video frame from pict into buf.
|
* Encode a video frame from pict into buf.
|
||||||
* The input picture should be
|
* The input picture should be
|
||||||
* stored using a specific format, namely avctx.pix_fmt.
|
* stored using a specific format, namely avctx.pix_fmt.
|
||||||
@ -3782,8 +3785,44 @@ int avcodec_fill_audio_frame(AVFrame *frame, int nb_channels,
|
|||||||
* @return On error a negative value is returned, on success zero or the number
|
* @return On error a negative value is returned, on success zero or the number
|
||||||
* of bytes used from the output buffer.
|
* of bytes used from the output buffer.
|
||||||
*/
|
*/
|
||||||
|
attribute_deprecated
|
||||||
int avcodec_encode_video(AVCodecContext *avctx, uint8_t *buf, int buf_size,
|
int avcodec_encode_video(AVCodecContext *avctx, uint8_t *buf, int buf_size,
|
||||||
const AVFrame *pict);
|
const AVFrame *pict);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encode a frame of video.
|
||||||
|
*
|
||||||
|
* Takes input raw video data from frame and writes the next output packet, if
|
||||||
|
* available, to avpkt. The output packet does not necessarily contain data for
|
||||||
|
* the most recent frame, as encoders can delay and reorder input frames
|
||||||
|
* internally as needed.
|
||||||
|
*
|
||||||
|
* @param avctx codec context
|
||||||
|
* @param avpkt output AVPacket.
|
||||||
|
* The user can supply an output buffer by setting
|
||||||
|
* avpkt->data and avpkt->size prior to calling the
|
||||||
|
* function, but if the size of the user-provided data is not
|
||||||
|
* large enough, encoding will fail. All other AVPacket fields
|
||||||
|
* will be reset by the encoder using av_init_packet(). If
|
||||||
|
* avpkt->data is NULL, the encoder will allocate it.
|
||||||
|
* The encoder will set avpkt->size to the size of the
|
||||||
|
* output packet. The returned data (if any) belongs to the
|
||||||
|
* caller, he is responsible for freeing it.
|
||||||
|
* @param[in] frame AVFrame containing the raw video data to be encoded.
|
||||||
|
* May be NULL when flushing an encoder that has the
|
||||||
|
* CODEC_CAP_DELAY capability set.
|
||||||
|
* @param[out] got_packet_ptr This field is set to 1 by libavcodec if the
|
||||||
|
* output packet is non-empty, and to 0 if it is
|
||||||
|
* empty. If the function returns an error, the
|
||||||
|
* packet can be assumed to be invalid, and the
|
||||||
|
* value of got_packet_ptr is undefined and should
|
||||||
|
* not be used.
|
||||||
|
* @return 0 on success, negative error code on failure
|
||||||
|
*/
|
||||||
|
int avcodec_encode_video2(AVCodecContext *avctx, AVPacket *avpkt,
|
||||||
|
const AVFrame *frame, int *got_packet_ptr);
|
||||||
|
|
||||||
int avcodec_encode_subtitle(AVCodecContext *avctx, uint8_t *buf, int buf_size,
|
int avcodec_encode_subtitle(AVCodecContext *avctx, uint8_t *buf, int buf_size,
|
||||||
const AVSubtitle *sub);
|
const AVSubtitle *sub);
|
||||||
|
|
||||||
|
@ -1034,25 +1034,109 @@ int attribute_align_arg avcodec_encode_audio(AVCodecContext *avctx,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if FF_API_OLD_ENCODE_VIDEO
|
||||||
int attribute_align_arg avcodec_encode_video(AVCodecContext *avctx, uint8_t *buf, int buf_size,
|
int attribute_align_arg avcodec_encode_video(AVCodecContext *avctx, uint8_t *buf, int buf_size,
|
||||||
const AVFrame *pict)
|
const AVFrame *pict)
|
||||||
{
|
{
|
||||||
|
AVPacket pkt;
|
||||||
|
int ret, got_packet = 0;
|
||||||
|
|
||||||
if(buf_size < FF_MIN_BUFFER_SIZE){
|
if(buf_size < FF_MIN_BUFFER_SIZE){
|
||||||
av_log(avctx, AV_LOG_ERROR, "buffer smaller than minimum size\n");
|
av_log(avctx, AV_LOG_ERROR, "buffer smaller than minimum size\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if(av_image_check_size(avctx->width, avctx->height, 0, avctx))
|
|
||||||
return -1;
|
|
||||||
if((avctx->codec->capabilities & CODEC_CAP_DELAY) || pict){
|
|
||||||
int ret = avctx->codec->encode(avctx, buf, buf_size, pict);
|
|
||||||
avctx->frame_number++;
|
|
||||||
emms_c(); //needed to avoid an emms_c() call before every return;
|
|
||||||
|
|
||||||
return ret;
|
av_init_packet(&pkt);
|
||||||
}else
|
pkt.data = buf;
|
||||||
|
pkt.size = buf_size;
|
||||||
|
|
||||||
|
ret = avcodec_encode_video2(avctx, &pkt, pict, &got_packet);
|
||||||
|
if (!ret && got_packet && avctx->coded_frame) {
|
||||||
|
avctx->coded_frame->pts = pkt.pts;
|
||||||
|
avctx->coded_frame->key_frame = !!(pkt.flags & AV_PKT_FLAG_KEY);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* free any side data since we cannot return it */
|
||||||
|
if (pkt.side_data_elems > 0) {
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < pkt.side_data_elems; i++)
|
||||||
|
av_free(pkt.side_data[i].data);
|
||||||
|
av_freep(&pkt.side_data);
|
||||||
|
pkt.side_data_elems = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret ? ret : pkt.size;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define MAX_CODED_FRAME_SIZE(width, height)\
|
||||||
|
(8*(width)*(height) + FF_MIN_BUFFER_SIZE)
|
||||||
|
|
||||||
|
int attribute_align_arg avcodec_encode_video2(AVCodecContext *avctx,
|
||||||
|
AVPacket *avpkt,
|
||||||
|
const AVFrame *frame,
|
||||||
|
int *got_packet_ptr)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
int user_packet = !!avpkt->data;
|
||||||
|
|
||||||
|
if (!(avctx->codec->capabilities & CODEC_CAP_DELAY) && !frame) {
|
||||||
|
av_init_packet(avpkt);
|
||||||
|
avpkt->size = 0;
|
||||||
|
*got_packet_ptr = 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (av_image_check_size(avctx->width, avctx->height, 0, avctx))
|
||||||
|
return AVERROR(EINVAL);
|
||||||
|
|
||||||
|
if (avctx->codec->encode2) {
|
||||||
|
*got_packet_ptr = 0;
|
||||||
|
ret = avctx->codec->encode2(avctx, avpkt, frame, got_packet_ptr);
|
||||||
|
if (!ret) {
|
||||||
|
if (!*got_packet_ptr)
|
||||||
|
avpkt->size = 0;
|
||||||
|
else if (!(avctx->codec->capabilities & CODEC_CAP_DELAY))
|
||||||
|
avpkt->pts = avpkt->dts = frame->pts;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* for compatibility with encoders not supporting encode2(), we need to
|
||||||
|
allocate a packet buffer if the user has not provided one or check
|
||||||
|
the size otherwise */
|
||||||
|
int buf_size = avpkt->size;
|
||||||
|
|
||||||
|
if (!user_packet)
|
||||||
|
buf_size = MAX_CODED_FRAME_SIZE(avctx->width, avctx->height);
|
||||||
|
|
||||||
|
if ((ret = ff_alloc_packet(avpkt, buf_size)))
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
/* encode the frame */
|
||||||
|
ret = avctx->codec->encode(avctx, avpkt->data, avpkt->size, frame);
|
||||||
|
if (ret >= 0) {
|
||||||
|
if (!ret) {
|
||||||
|
/* no output. if the packet data was allocated by libavcodec,
|
||||||
|
free it */
|
||||||
|
if (!user_packet)
|
||||||
|
av_freep(&avpkt->data);
|
||||||
|
} else if (avctx->coded_frame) {
|
||||||
|
avpkt->pts = avctx->coded_frame->pts;
|
||||||
|
avpkt->flags |= AV_PKT_FLAG_KEY*avctx->coded_frame->key_frame;
|
||||||
|
}
|
||||||
|
|
||||||
|
avpkt->size = ret;
|
||||||
|
*got_packet_ptr = (ret > 0);
|
||||||
|
ret = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ret)
|
||||||
|
avctx->frame_number++;
|
||||||
|
|
||||||
|
emms_c();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
int avcodec_encode_subtitle(AVCodecContext *avctx, uint8_t *buf, int buf_size,
|
int avcodec_encode_subtitle(AVCodecContext *avctx, uint8_t *buf, int buf_size,
|
||||||
const AVSubtitle *sub)
|
const AVSubtitle *sub)
|
||||||
{
|
{
|
||||||
|
@ -47,5 +47,8 @@
|
|||||||
#ifndef FF_API_OLD_ENCODE_AUDIO
|
#ifndef FF_API_OLD_ENCODE_AUDIO
|
||||||
#define FF_API_OLD_ENCODE_AUDIO (LIBAVCODEC_VERSION_MAJOR < 55)
|
#define FF_API_OLD_ENCODE_AUDIO (LIBAVCODEC_VERSION_MAJOR < 55)
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef FF_API_OLD_ENCODE_VIDEO
|
||||||
|
#define FF_API_OLD_ENCODE_VIDEO (LIBAVCODEC_VERSION_MAJOR < 55)
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* AVCODEC_VERSION_H */
|
#endif /* AVCODEC_VERSION_H */
|
||||||
|
Loading…
Reference in New Issue
Block a user