mirror of
https://github.com/Motion-Project/motion.git
synced 2026-02-05 12:31:43 -05:00
ffmpeg 3.0 fixes
This commit is contained in:
90
ffmpeg.c
90
ffmpeg.c
@@ -79,6 +79,64 @@ void my_frame_free(AVFrame *frame){
|
||||
av_freep(&frame);
|
||||
#endif
|
||||
}
|
||||
/*********************************************/
|
||||
int my_image_get_buffer_size(enum AVPixelFormat pix_fmt, int width, int height){
|
||||
int retcd = 0;
|
||||
#if (LIBAVFORMAT_VERSION_MAJOR >= 57)
|
||||
int align = 1;
|
||||
retcd = av_image_get_buffer_size(pix_fmt, width, height, align);
|
||||
#else
|
||||
retcd = avpicture_get_size(pix_fmt, width, height);
|
||||
#endif
|
||||
return retcd;
|
||||
}
|
||||
/*********************************************/
|
||||
int my_image_copy_to_buffer(AVFrame *frame, uint8_t *buffer_ptr, enum AVPixelFormat pix_fmt,int width, int height,int dest_size){
|
||||
int retcd = 0;
|
||||
#if (LIBAVFORMAT_VERSION_MAJOR >= 57)
|
||||
int align = 1;
|
||||
retcd = av_image_copy_to_buffer((uint8_t *)buffer_ptr,dest_size
|
||||
,(const uint8_t * const*)frame,frame->linesize,pix_fmt,width,height,align);
|
||||
#else
|
||||
retcd = avpicture_layout((const AVPicture*)frame,pix_fmt,width,height
|
||||
,(unsigned char *)buffer_ptr,dest_size);
|
||||
#endif
|
||||
return retcd;
|
||||
}
|
||||
/*********************************************/
|
||||
int my_image_fill_arrays(AVFrame *frame,uint8_t *buffer_ptr,enum AVPixelFormat pix_fmt,int width,int height){
|
||||
int retcd = 0;
|
||||
#if (LIBAVFORMAT_VERSION_MAJOR >= 57)
|
||||
int align = 1;
|
||||
retcd = av_image_fill_arrays(
|
||||
frame->data
|
||||
,frame->linesize
|
||||
,buffer_ptr
|
||||
,pix_fmt
|
||||
,width
|
||||
,height
|
||||
,align
|
||||
);
|
||||
#else
|
||||
retcd = avpicture_fill(
|
||||
(AVPicture *)frame
|
||||
,buffer_ptr
|
||||
,pix_fmt
|
||||
,width
|
||||
,height);
|
||||
#endif
|
||||
return retcd;
|
||||
}
|
||||
/*********************************************/
|
||||
void my_packet_unref(AVPacket pkt){
|
||||
#if (LIBAVFORMAT_VERSION_MAJOR >= 57)
|
||||
av_packet_unref(&pkt);
|
||||
#else
|
||||
av_free_packet(&pkt);
|
||||
#endif
|
||||
}
|
||||
/*********************************************/
|
||||
|
||||
/****************************************************************************
|
||||
****************************************************************************
|
||||
****************************************************************************/
|
||||
@@ -219,7 +277,7 @@ struct ffmpeg *ffmpeg_open(const char *ffmpeg_video_codec, char *filename,
|
||||
AVCodecContext *c;
|
||||
AVCodec *codec;
|
||||
struct ffmpeg *ffmpeg;
|
||||
int ret;
|
||||
int retcd;
|
||||
char errstr[128];
|
||||
AVDictionary *opts = 0;
|
||||
|
||||
@@ -312,9 +370,9 @@ struct ffmpeg *ffmpeg_open(const char *ffmpeg_video_codec, char *filename,
|
||||
}
|
||||
|
||||
pthread_mutex_lock(&global_lock);
|
||||
ret = avcodec_open2(c, codec, &opts);
|
||||
retcd = avcodec_open2(c, codec, &opts);
|
||||
pthread_mutex_unlock(&global_lock);
|
||||
if (ret < 0) {
|
||||
if (retcd < 0) {
|
||||
if (codec->supported_framerates) {
|
||||
const AVRational *fps = codec->supported_framerates;
|
||||
while (fps->num) {
|
||||
@@ -324,14 +382,14 @@ struct ffmpeg *ffmpeg_open(const char *ffmpeg_video_codec, char *filename,
|
||||
}
|
||||
int chkrate = 1;
|
||||
pthread_mutex_lock(&global_lock);
|
||||
while ((chkrate < 36) && (ret != 0)) {
|
||||
while ((chkrate < 36) && (retcd != 0)) {
|
||||
c->time_base.den = chkrate;
|
||||
ret = avcodec_open2(c, codec, &opts);
|
||||
retcd = avcodec_open2(c, codec, &opts);
|
||||
chkrate++;
|
||||
}
|
||||
pthread_mutex_unlock(&global_lock);
|
||||
if (ret < 0){
|
||||
av_strerror(ret, errstr, sizeof(errstr));
|
||||
if (retcd < 0){
|
||||
av_strerror(retcd, errstr, sizeof(errstr));
|
||||
MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO, "%s: Could not open codec %s",errstr);
|
||||
av_dict_free(&opts);
|
||||
ffmpeg_cleanups(ffmpeg);
|
||||
@@ -399,7 +457,13 @@ struct ffmpeg *ffmpeg_open(const char *ffmpeg_video_codec, char *filename,
|
||||
* we write the data via standard file I/O so we close the
|
||||
* items here
|
||||
*/
|
||||
avformat_write_header(ffmpeg->oc, NULL);
|
||||
retcd = avformat_write_header(ffmpeg->oc, NULL);
|
||||
if (retcd < 0){
|
||||
av_strerror(retcd, errstr, sizeof(errstr));
|
||||
MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO, "%s: Could not write ffmpeg header %s",errstr);
|
||||
ffmpeg_cleanups(ffmpeg);
|
||||
return NULL;
|
||||
}
|
||||
if (ffmpeg->tlapse == TIMELAPSE_APPEND) {
|
||||
av_write_trailer(ffmpeg->oc);
|
||||
avio_close(ffmpeg->oc->pb);
|
||||
@@ -573,7 +637,7 @@ int ffmpeg_put_frame(struct ffmpeg *ffmpeg, AVFrame *pic){
|
||||
}
|
||||
if (got_packet_ptr == 0){
|
||||
//Buffered packet. Throw special return code
|
||||
av_free_packet(&pkt);
|
||||
my_packet_unref(pkt);
|
||||
return -2;
|
||||
}
|
||||
if (pkt.pts != AV_NOPTS_VALUE)
|
||||
@@ -590,7 +654,7 @@ int ffmpeg_put_frame(struct ffmpeg *ffmpeg, AVFrame *pic){
|
||||
} else {
|
||||
retcd = av_write_frame(ffmpeg->oc, &pkt);
|
||||
}
|
||||
av_free_packet(&pkt);
|
||||
my_packet_unref(pkt);
|
||||
|
||||
if (retcd != 0) {
|
||||
MOTION_LOG(ERR, TYPE_ENCODER, SHOW_ERRNO, "%s: Error while writing video frame");
|
||||
@@ -617,12 +681,12 @@ int ffmpeg_put_frame(struct ffmpeg *ffmpeg, AVFrame *pic){
|
||||
ffmpeg->video_outbuf_size, pic);
|
||||
if (retcd < 0 ){
|
||||
MOTION_LOG(ERR, TYPE_ENCODER, SHOW_ERRNO, "%s: Error encoding video");
|
||||
av_free_packet(&pkt);
|
||||
my_packet_unref(pkt);
|
||||
return -1;
|
||||
}
|
||||
if (retcd == 0 ){
|
||||
// No bytes encoded => buffered=>special handling
|
||||
av_free_packet(&pkt);
|
||||
my_packet_unref(pkt);
|
||||
return -2;
|
||||
}
|
||||
|
||||
@@ -637,7 +701,7 @@ int ffmpeg_put_frame(struct ffmpeg *ffmpeg, AVFrame *pic){
|
||||
} else {
|
||||
retcd = av_write_frame(ffmpeg->oc, &pkt);
|
||||
}
|
||||
av_free_packet(&pkt);
|
||||
my_packet_unref(pkt);
|
||||
|
||||
if (retcd != 0) {
|
||||
MOTION_LOG(ERR, TYPE_ENCODER, SHOW_ERRNO, "%s: Error while writing video frame");
|
||||
|
||||
6
ffmpeg.h
6
ffmpeg.h
@@ -10,6 +10,7 @@
|
||||
|
||||
#include <errno.h>
|
||||
#include <libavformat/avformat.h>
|
||||
#include <libavutil/imgutils.h>
|
||||
#include <libavutil/mathematics.h>
|
||||
|
||||
#if (LIBAVFORMAT_VERSION_MAJOR >= 56)
|
||||
@@ -91,6 +92,11 @@ int ffmpeg_put_frame(struct ffmpeg *, AVFrame *);
|
||||
void ffmpeg_cleanups(struct ffmpeg *);
|
||||
AVFrame *ffmpeg_prepare_frame(struct ffmpeg *, unsigned char *,
|
||||
unsigned char *, unsigned char *);
|
||||
int my_image_get_buffer_size(enum AVPixelFormat pix_fmt, int width, int height);
|
||||
int my_image_copy_to_buffer(AVFrame *frame,uint8_t *buffer_ptr,enum AVPixelFormat pix_fmt,int width,int height,int dest_size);
|
||||
int my_image_fill_arrays(AVFrame *frame,uint8_t *buffer_ptr,enum AVPixelFormat pix_fmt,int width,int height);
|
||||
void my_packet_unref(AVPacket pkt);
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* _INCLUDE_FFMPEG_H_ */
|
||||
|
||||
@@ -133,10 +133,10 @@ static void netcam_buffsize_rtsp(netcam_buff_ptr buff, size_t numbytes){
|
||||
static int decode_packet(AVPacket *packet, netcam_buff_ptr buffer, AVFrame *frame, AVCodecContext *cc){
|
||||
int check = 0;
|
||||
int frame_size = 0;
|
||||
int ret = 0;
|
||||
int retcd = 0;
|
||||
|
||||
ret = avcodec_decode_video2(cc, frame, &check, packet);
|
||||
if (ret < 0) {
|
||||
retcd = avcodec_decode_video2(cc, frame, &check, packet);
|
||||
if (retcd < 0) {
|
||||
MOTION_LOG(ERR, TYPE_NETCAM, NO_ERRNO, "%s: Error decoding video packet");
|
||||
return 0;
|
||||
}
|
||||
@@ -145,12 +145,15 @@ static int decode_packet(AVPacket *packet, netcam_buff_ptr buffer, AVFrame *fram
|
||||
return 0;
|
||||
}
|
||||
|
||||
frame_size = avpicture_get_size(cc->pix_fmt, cc->width, cc->height);
|
||||
frame_size = my_image_get_buffer_size(cc->pix_fmt, cc->width, cc->height);
|
||||
|
||||
netcam_buffsize_rtsp(buffer, frame_size);
|
||||
|
||||
avpicture_layout((const AVPicture*)frame,cc->pix_fmt,cc->width,cc->height
|
||||
,(unsigned char *)buffer->ptr,frame_size );
|
||||
retcd = my_image_copy_to_buffer(frame, (uint8_t *)buffer->ptr,cc->pix_fmt,cc->width,cc->height, frame_size);
|
||||
if (retcd < 0) {
|
||||
MOTION_LOG(ERR, TYPE_NETCAM, NO_ERRNO, "%s: Error decoding video packet: Copying to buffer");
|
||||
return 0;
|
||||
}
|
||||
|
||||
buffer->used = frame_size;
|
||||
|
||||
@@ -313,7 +316,7 @@ int netcam_read_rtsp_image(netcam_context_ptr netcam){
|
||||
netcam->rtsp->readingframe = 1;
|
||||
while (size_decoded == 0 && av_read_frame(netcam->rtsp->format_context, &packet) >= 0) {
|
||||
if(packet.stream_index != netcam->rtsp->video_stream_index) {
|
||||
av_free_packet(&packet);
|
||||
my_packet_unref(packet);
|
||||
av_init_packet(&packet);
|
||||
packet.data = NULL;
|
||||
packet.size = 0;
|
||||
@@ -322,7 +325,7 @@ int netcam_read_rtsp_image(netcam_context_ptr netcam){
|
||||
}
|
||||
size_decoded = decode_packet(&packet, buffer, netcam->rtsp->frame, netcam->rtsp->codec_context);
|
||||
|
||||
av_free_packet(&packet);
|
||||
my_packet_unref(packet);
|
||||
av_init_packet(&packet);
|
||||
packet.data = NULL;
|
||||
packet.size = 0;
|
||||
@@ -330,7 +333,7 @@ int netcam_read_rtsp_image(netcam_context_ptr netcam){
|
||||
netcam->rtsp->readingframe = 0;
|
||||
|
||||
// at this point, we are finished with the packet
|
||||
av_free_packet(&packet);
|
||||
my_packet_unref(packet);
|
||||
|
||||
if (size_decoded == 0) {
|
||||
// something went wrong, end of stream? Interupted?
|
||||
@@ -575,17 +578,17 @@ int netcam_rtsp_open_sws(netcam_context_ptr netcam){
|
||||
return -1;
|
||||
}
|
||||
|
||||
netcam->rtsp->swsframe_size = avpicture_get_size(
|
||||
netcam->rtsp->swsframe_size = my_image_get_buffer_size(
|
||||
MY_PIX_FMT_YUV420P
|
||||
,netcam->width
|
||||
,netcam->height);
|
||||
if (netcam->rtsp->swsframe_size <= 0) {
|
||||
if (netcam->rtsp->status == RTSP_NOTCONNECTED){
|
||||
MOTION_LOG(ERR, TYPE_NETCAM, NO_ERRNO, "%s: Error determining size of frame out");
|
||||
}
|
||||
netcam_rtsp_close_context(netcam);
|
||||
return -1;
|
||||
if (netcam->rtsp->swsframe_size <= 0) {
|
||||
if (netcam->rtsp->status == RTSP_NOTCONNECTED){
|
||||
MOTION_LOG(ERR, TYPE_NETCAM, NO_ERRNO, "%s: Error determining size of frame out");
|
||||
}
|
||||
netcam_rtsp_close_context(netcam);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -611,8 +614,8 @@ int netcam_rtsp_resize(unsigned char *image , netcam_context_ptr netcam){
|
||||
char errstr[128];
|
||||
uint8_t *buffer_out;
|
||||
|
||||
retcd = avpicture_fill(
|
||||
(AVPicture*)netcam->rtsp->swsframe_in
|
||||
retcd=my_image_fill_arrays(
|
||||
netcam->rtsp->swsframe_in
|
||||
,(uint8_t*)netcam->latest->ptr
|
||||
,netcam->rtsp->codec_context->pix_fmt
|
||||
,netcam->rtsp->codec_context->width
|
||||
@@ -629,8 +632,8 @@ int netcam_rtsp_resize(unsigned char *image , netcam_context_ptr netcam){
|
||||
|
||||
buffer_out=(uint8_t *)av_malloc(netcam->rtsp->swsframe_size*sizeof(uint8_t));
|
||||
|
||||
retcd = avpicture_fill(
|
||||
(AVPicture*)netcam->rtsp->swsframe_out
|
||||
retcd=my_image_fill_arrays(
|
||||
netcam->rtsp->swsframe_out
|
||||
,buffer_out
|
||||
,MY_PIX_FMT_YUV420P
|
||||
,netcam->width
|
||||
@@ -661,13 +664,13 @@ int netcam_rtsp_resize(unsigned char *image , netcam_context_ptr netcam){
|
||||
return -1;
|
||||
}
|
||||
|
||||
retcd = avpicture_layout(
|
||||
(const AVPicture*)netcam->rtsp->swsframe_out
|
||||
retcd=my_image_copy_to_buffer(
|
||||
netcam->rtsp->swsframe_out
|
||||
,(uint8_t *)image
|
||||
,MY_PIX_FMT_YUV420P
|
||||
,netcam->width
|
||||
,netcam->height
|
||||
,(unsigned char *)image
|
||||
,netcam->rtsp->swsframe_size );
|
||||
,netcam->rtsp->swsframe_size);
|
||||
if (retcd < 0) {
|
||||
if (netcam->rtsp->status == RTSP_NOTCONNECTED){
|
||||
av_strerror(retcd, errstr, sizeof(errstr));
|
||||
@@ -874,7 +877,7 @@ int netcam_setup_rtsp(netcam_context_ptr netcam, struct url_t *url){
|
||||
av_register_all();
|
||||
avcodec_register_all();
|
||||
pthread_mutex_unlock(&global_lock);
|
||||
|
||||
|
||||
/*
|
||||
* The RTSP context should be all ready to attempt a connection with
|
||||
* the server, so we try ....
|
||||
|
||||
Reference in New Issue
Block a user