libavcodec完全在内存中的媒体上

时间:2019-01-10 23:48:31

标签: c++ ffmpeg libavcodec

我正在处理完全存在于内存中(作为字符串)的小型微型视频。到目前为止,我还无法获得avcodec以这种方式正确解码h264。

我尝试了在容器化媒体上运行的自定义AVIOContext:

struct Stream { char* str; size_t pos; size_t size; };

static int ReadStream(void* opaque, uint8* buf, int buf_size) {
  Stream* strm = reinterpret_cast<Stream*>(opaque);
  int read = strm->size-strm->pos;
  read = read < buf_size ? read : buf_size;
  memcpy(buf, strm->str+strm->pos, read);
  memset(buf+read, 0, buf_size-read);
  strm->pos += read;
  return read;
}

static int64_t SeekStream(void *opaque, int64_t offset, int whence) {
  Stream* strm = reinterpret_cast<Stream*>(opaque);
  if (whence == AVSEEK_SIZE) {
    return strm->size;
  } else if (whence == SEEK_END) {
    strm->pos = strm->size;
  } else if (whence == SEEK_SET) {
    strm->pos = 0;
  }
  strm->pos += offset;
  return strm->pos;
}

int main(int argc, char *argv[]) {
  string content;
  GetContents("test.mp4", &content);

  avcodec_register_all();

  uint8* buff = (uint8*)malloc(4096 + AV_INPUT_BUFFER_PADDING_SIZE);
  Stream strm = { const_cast<char*>(content.data()), 0, content.size() };
  void* opaque = reinterpret_cast<void*>(&strm);

  AVFormatContext* fmtctx = avformat_alloc_context();
  AVIOContext* avctx = avio_alloc_context(buff, 4096, 0, opaque, &ReadStream, nullptr, &SeekStream);
  AVInputFormat* ifmt = av_find_input_format("mp4");
  AVDictionary* opts = nullptr;

  fmtctx->pb = avctx;
  avformat_open_input(&fmtctx, "", ifmt, &opts);
  avformat_find_stream_info(fmtctx, &opts);
}

但这总是在find_stream_info中出现段错误。

我还尝试了将视频流预解复用为原始h264,然后仅发送流数据包(例如):

int main(int argc, char *argv[]) {
  string content;
  GetContents("test.h264", &content);
  uint8* data = reinterpret_cast<uint8*>(const_cast<char*>(content.c_str()));

  avcodec_register_all();

  AVCodec* codec = avcodec_find_decoder(AV_CODEC_ID_H264);
  AVCodecContext* ctx = avcodec_alloc_context3(codec);

  ctx->width = 1080;
  ctx->height = 1920;
  avcodec_open2(ctx, codec, nullptr);

  AVPacket* pkt = av_packet_alloc();    
  AVFrame* frame = av_frame_alloc();

  pkt->data = data;
  pkt->size = 4096;
  avcodec_send_packet(ctx, pkt);
  data += 4096;
}

但是,这仅给出了一个非描述性的“解码MB##字节流#时出错”。请注意,为了简化代码,我已经从allocs等中删除了错误检查,但是我正在检查以确保所有内容均已正确分配和实例化。

关于我对avcodec的误解或误用在哪里的任何建议?

0 个答案:

没有答案