Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Ensure no modification to FFmpeg libavformat's URLProtocol change wou…

…ld break our code

FFmpeg's recently changed the structure of the URLProtocol object, which broke our code.
While this time it caused a compilation error and was easy to spot, it could have changed in such a way that it would have compiled properly and cause runtime crash.

C++ doesn't have C99 designated initialisers, so do it another way. Clean up avfringbuffer while at it
  • Loading branch information...
commit 4963b9dcacfdbc4dd438354f6f81380ed5588c45 1 parent 3369fcf
Jean-Yves Avenard jyavenard authored
33 mythtv/libs/libmythtv/avformatdecoder.cpp
View
@@ -809,24 +809,23 @@ bool AvFormatDecoder::CanHandle(char testbuf[kDecoderProbeBufferSize],
void AvFormatDecoder::InitByteContext(void)
{
- int buf_size = ringBuffer->BestBufferSize();
- int streamed = ringBuffer->IsStreamed();
- LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("Buffer size: %1, streamed %2")
- .arg(buf_size).arg(streamed));
-
- readcontext.prot = &AVF_RingBuffer_Protocol;
- readcontext.flags = AVIO_FLAG_READ;
- readcontext.is_streamed = streamed;
+ int buf_size = ringBuffer->BestBufferSize();
+ int streamed = ringBuffer->IsStreamed();
+ readcontext.prot = AVFRingBuffer::GetRingBufferURLProtocol();
+ readcontext.flags = AVIO_FLAG_READ;
+ readcontext.is_streamed = streamed;
readcontext.max_packet_size = 0;
- readcontext.priv_data = avfRingBuffer;
- unsigned char* buffer = (unsigned char *)av_malloc(buf_size);
- ic->pb = avio_alloc_context(buffer, buf_size, 0,
- &readcontext,
- AVF_Read_Packet,
- AVF_Write_Packet,
- AVF_Seek_Packet);
-
- ic->pb->seekable = !streamed;
+ readcontext.priv_data = avfRingBuffer;
+ unsigned char* buffer = (unsigned char *)av_malloc(buf_size);
+ ic->pb = avio_alloc_context(buffer, buf_size, 0,
+ &readcontext,
+ AVFRingBuffer::AVF_Read_Packet,
+ AVFRingBuffer::AVF_Write_Packet,
+ AVFRingBuffer::AVF_Seek_Packet);
+
+ ic->pb->seekable = !streamed;
+ LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("Buffer size: %1, streamed %2")
+ .arg(buf_size).arg(streamed));
}
extern "C" void HandleStreamChange(void *data)
8 mythtv/libs/libmythtv/avformatwriter.cpp
View
@@ -210,10 +210,10 @@ bool AVFormatWriter::OpenFile(void)
return false;
}
- m_avfRingBuffer = new AVFRingBuffer(m_ringBuffer);
- URLContext *uc = (URLContext *)m_ctx->pb->opaque;
- uc->prot = &AVF_RingBuffer_Protocol;
- uc->priv_data = (void *)m_avfRingBuffer;
+ m_avfRingBuffer = new AVFRingBuffer(m_ringBuffer);
+ URLContext *uc = (URLContext *)m_ctx->pb->opaque;
+ uc->prot = AVFRingBuffer::GetRingBufferURLProtocol();
+ uc->priv_data = (void *)m_avfRingBuffer;
avformat_write_header(m_ctx, NULL);
59 mythtv/libs/libmythtv/avfringbuffer.cpp
View
@@ -1,6 +1,10 @@
#include "avfringbuffer.h"
+#include "mythcorecontext.h"
-static int AVF_Open(URLContext *h, const char *filename, int flags)
+bool AVFRingBuffer::m_avrprotocol_initialised = false;
+URLProtocol AVFRingBuffer::m_avfrURL;
+
+int AVFRingBuffer::AVF_Open(URLContext *h, const char *filename, int flags)
{
(void)filename;
(void)flags;
@@ -9,7 +13,7 @@ static int AVF_Open(URLContext *h, const char *filename, int flags)
return 0;
}
-static int AVF_Read(URLContext *h, uint8_t *buf, int buf_size)
+int AVFRingBuffer::AVF_Read(URLContext *h, uint8_t *buf, int buf_size)
{
AVFRingBuffer *avfr = (AVFRingBuffer *)h->priv_data;
@@ -19,7 +23,7 @@ static int AVF_Read(URLContext *h, uint8_t *buf, int buf_size)
return avfr->GetRingBuffer()->Read(buf, buf_size);
}
-static int AVF_Write(URLContext *h, const uint8_t *buf, int buf_size)
+int AVFRingBuffer::AVF_Write(URLContext *h, const uint8_t *buf, int buf_size)
{
AVFRingBuffer *avfr = (AVFRingBuffer *)h->priv_data;
@@ -29,7 +33,7 @@ static int AVF_Write(URLContext *h, const uint8_t *buf, int buf_size)
return avfr->GetRingBuffer()->Write(buf, buf_size);
}
-static int64_t AVF_Seek(URLContext *h, int64_t offset, int whence)
+int64_t AVFRingBuffer::AVF_Seek(URLContext *h, int64_t offset, int whence)
{
AVFRingBuffer *avfr = (AVFRingBuffer *)h->priv_data;
@@ -45,32 +49,13 @@ static int64_t AVF_Seek(URLContext *h, int64_t offset, int whence)
return avfr->GetRingBuffer()->Seek(offset, whence);
}
-static int AVF_Close(URLContext *h)
+int AVFRingBuffer::AVF_Close(URLContext *h)
{
(void)h;
return 0;
}
-URLProtocol AVF_RingBuffer_Protocol = {
- "rbuffer",
- AVF_Open,
- NULL, // open2
- AVF_Read,
- AVF_Write,
- AVF_Seek,
- AVF_Close,
- NULL, // next
- NULL, // read_pause
- NULL, // read_seek
- NULL, // get_file_handle
- NULL, // shutdown
- 0, // priv_data_size
- NULL, // priv_data_class
- URL_PROTOCOL_FLAG_NETWORK, // flags
- NULL // url_check
-};
-
-int AVF_Write_Packet(void *opaque, uint8_t *buf, int buf_size)
+int AVFRingBuffer::AVF_Write_Packet(void *opaque, uint8_t *buf, int buf_size)
{
if (!opaque)
return 0;
@@ -78,7 +63,7 @@ int AVF_Write_Packet(void *opaque, uint8_t *buf, int buf_size)
return ffurl_write((URLContext *)opaque, buf, buf_size);
}
-int AVF_Read_Packet(void *opaque, uint8_t *buf, int buf_size)
+int AVFRingBuffer::AVF_Read_Packet(void *opaque, uint8_t *buf, int buf_size)
{
if (!opaque)
return 0;
@@ -86,7 +71,7 @@ int AVF_Read_Packet(void *opaque, uint8_t *buf, int buf_size)
return ffurl_read((URLContext *)opaque, buf, buf_size);
}
-int64_t AVF_Seek_Packet(void *opaque, int64_t offset, int whence)
+int64_t AVFRingBuffer::AVF_Seek_Packet(void *opaque, int64_t offset, int whence)
{
if (!opaque)
return 0;
@@ -94,4 +79,24 @@ int64_t AVF_Seek_Packet(void *opaque, int64_t offset, int whence)
return ffurl_seek((URLContext *)opaque, offset, whence);
}
+URLProtocol *AVFRingBuffer::GetRingBufferURLProtocol(void)
+{
+ QMutexLocker lock(avcodeclock);
+ if (!m_avrprotocol_initialised)
+ {
+ // just in case URLProtocol's members do not have default constructor
+ memset((void *)&m_avfrURL, 0, sizeof(m_avfrURL));
+ m_avfrURL.name = "rbuffer";
+ m_avfrURL.url_open = AVF_Open;
+ m_avfrURL.url_read = AVF_Read;
+ m_avfrURL.url_write = AVF_Write;
+ m_avfrURL.url_seek = AVF_Seek;
+ m_avfrURL.url_close = AVF_Close;
+ m_avfrURL.priv_data_size = 0;
+ m_avfrURL.flags = URL_PROTOCOL_FLAG_NETWORK;
+ m_avrprotocol_initialised = true;
+ }
+ return &m_avfrURL;
+}
+
/* vim: set expandtab tabstop=4 shiftwidth=4: */
34 mythtv/libs/libmythtv/avfringbuffer.h
View
@@ -10,20 +10,32 @@ extern "C" {
extern URLProtocol AVF_RingBuffer_Protocol;
-extern int AVF_Write_Packet(void *opaque, uint8_t *buf, int buf_size);
-extern int AVF_Read_Packet(void *opaque, uint8_t *buf, int buf_size);
-extern int64_t AVF_Seek_Packet(void *opaque, int64_t offset, int whence);
-
class AVFRingBuffer
{
- public:
+public:
AVFRingBuffer(RingBuffer *rbuffer = NULL) { m_rbuffer = rbuffer; }
-
- void SetRingBuffer(RingBuffer *rbuffer) { m_rbuffer = rbuffer; }
- RingBuffer *GetRingBuffer(void) { return m_rbuffer; }
-
- private:
- RingBuffer *m_rbuffer;
+ void SetRingBuffer(RingBuffer *rbuffer)
+ {
+ m_rbuffer = rbuffer;
+ }
+ RingBuffer *GetRingBuffer(void)
+ {
+ return m_rbuffer;
+ }
+ static URLProtocol *GetRingBufferURLProtocol(void);
+ static int AVF_Write_Packet(void *opaque, uint8_t *buf, int buf_size);
+ static int AVF_Read_Packet(void *opaque, uint8_t *buf, int buf_size);
+ static int64_t AVF_Seek_Packet(void *opaque, int64_t offset, int whence);
+ static int AVF_Open(URLContext *h, const char *filename, int flags);
+ static int AVF_Read(URLContext *h, uint8_t *buf, int buf_size);
+ static int AVF_Write(URLContext *h, const uint8_t *buf, int buf_size);
+ static int64_t AVF_Seek(URLContext *h, int64_t offset, int whence);
+ static int AVF_Close(URLContext *h);
+
+private:
+ RingBuffer *m_rbuffer;
+ static bool m_avrprotocol_initialised;
+ static URLProtocol m_avfrURL;
};
#endif
Please sign in to comment.
Something went wrong with that request. Please try again.