请教一个关于ffmpeg的问题.
ffmpeg中有一个av_open_input_stream方法,可以从流中读取信息.
我只能拿到一个网页的视频文件流,而在此方法中需要的是ByteIOContext结构的参数.
请问一下 如何构造此函数? 其他一些参数该如何定义或设置?
/** * Bytestream IO Context. * New fields can be added to the end with minor version bumps. * Removal, reordering and changes to existing fields require a major * version bump. * sizeof(ByteIOContext) must not be used outside libav*. */typedef struct { unsigned char *buffer;//这里可以直接放字节序列的流 int buffer_size;////数据缓冲区的大小。/****想请问一下,下面的参数该如何设置或定义?**/ unsigned char *buf_ptr, *buf_end; void *opaque; int (*read_packet)(void *opaque, uint8_t *buf, int buf_size); int (*write_packet)(void *opaque, uint8_t *buf, int buf_size); int64_t (*seek)(void *opaque, int64_t offset, int whence); int64_t pos; /**< position in the file of the current buffer */ int must_flush; /**< true if the next seek should flush */ int eof_reached; /**< true if eof reached */ int write_flag; /**< true if open for writing */ int is_streamed; int max_packet_size; unsigned long checksum; unsigned char *checksum_ptr; unsigned long (*update_checksum)(unsigned long checksum, const uint8_t *buf, unsigned int size); int error; ///< contains the error code or 0 if no error happened int (*read_pause)(void *opaque, int pause); int64_t (*read_seek)(void *opaque, int stream_index, int64_t timestamp, int flags);} ByteIOContext;
class CFFMpegParser{public: uint8_t *m_buf; // 内存指针 int m_pos; // 正在读的位置(初始为0) int m_len; // 内存大小 ......}static int read_packet(void *opaque, uint8_t *buf, int buf_size){ CFFMpegParser *parser = (CFFMpegParser *)opaque; int nLen = min(parser->m_len - parser->m_pos, buf_size); memcpy(buf, parser->m_buf + parser->m_pos, nLen); parser->m_pos += nLen; return nLen;}static offset_t seek(void *opaque, offset_t offset, int whence){ CFFMpegParser *parser = (CFFMpegParser *)opaque; if(whence == AVSEEK_SIZE) return parser->m_len; switch(whence) { case SEEK_SET: m_pos = offset; break; case SEEK_CUR: m_pos += offset; break; case SEEK_END: m_pos = m_len + offset break; } m_pos = max(0, min(m_len, m_pos)); return m_pos;}BOOL CFFMpegParser::Parse(){ // m_buf 赋值OK // m_len 赋值OK m_pos = 0; m_dwIOBufferSize = AVCODEC_MAX_AUDIO_FRAME_SIZE; m_pIOBuffer = new BYTE[m_dwIOBufferSize]; memset(m_pIOBuffer, 0, m_dwIOBufferSize); m_pIO = av_alloc_put_byte(m_pIOBuffer, m_dwIOBufferSize, 0, this, ::read_packet, NULL, ::seek); m_pIO->is_streamed = 1; // 能seek到每一个位置可设为0,否则设成1(有些属性不去获取) AVProbeData data; data.filename = NULL; data.buf = m_pIO->buffer; data.buf_size = m_pIO->read_packet(m_pIO->opaque, m_pIO->buffer, m_pIO->buffer_size); if(data.buf_size < 100) return FALSE; m_pIO->pos = data.buf_size; m_pIO->buf_ptr = m_pIO->buffer; m_pIO->buf_end = m_pIO->buffer + data.buf_size; // AVInputFormat::read_probe (自己根据需要写) url_fseek(m_pIO, 0, SEEK_SET); if(av_open_input_stream(&m_pContext, m_pIO, "", *it, NULL) == 0) { ...... return TRUE; } return FALSE;}
[解决办法]
ffmpeg源码里的ffserver.c文件里这样写道:
static void compute_status(HTTPContext *c){ HTTPContext *c1; FFStream *stream; char *p; time_t ti; int i, len; ByteIOContext *pb; if (url_open_dyn_buf(&pb) < 0) { /* XXX: return an error ? */ c->buffer_ptr = c->buffer; c->buffer_end = c->buffer; return; } url_fprintf(pb, "HTTP/1.0 200 OK\r\n"); url_fprintf(pb, "Content-type: %s\r\n", "text/html"); url_fprintf(pb, "Pragma: no-cache\r\n"); url_fprintf(pb, "\r\n"); url_fprintf(pb, "<html><head><title>%s Status</title>\n", program_name); if (c->stream->feed_filename[0]) url_fprintf(pb, "<link rel=\"shortcut icon\" href=\"%s\">\n", c->stream->feed_filename); url_fprintf(pb, "</head>\n<body>"); url_fprintf(pb, "<h1>%s Status</h1>\n", program_name); /* format status */ url_fprintf(pb, "<h2>Available Streams</h2>\n"); url_fprintf(pb, "<table cellspacing=0 cellpadding=4>\n"); url_fprintf(pb, "<tr><th valign=top>Path<th align=left>Served<br>Conns<th><br>bytes<th valign=top>Format<th>Bit rate<br>kbits/s<th align=left>Video<br>kbits/s<th><br>Codec<th align=left>Audio<br>kbits/s<th><br>Codec<th align=left valign=top>Feed\n"); stream = first_stream; while (stream != NULL) { char sfilename[1024]; char *eosf;
[解决办法]
我也顶
[解决办法]
接分升星星
[解决办法]
主要是那个结构体里的函数指针要初始化,你研究一下ffmpeg文档中的例子,可能需要定义自己的那些read_packet和write_packet函数seek函数。
你这个比较专业,要耐心看文档。
[解决办法]
应该有相关接口。