Я имею дело с небольшими микро-видео, которые существуют полностью в памяти (в виде строки). До сих пор я не смог заставить 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);
}
Но это всегда segfaults в find_stream_info.
Я также пытался предварительно демодулировать видеопоток в raw 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 # #, bytestream #». Обратите внимание, что я удалил проверку ошибок из allocs и т. Д., Чтобы упростить код, но я проверяю, чтобы убедиться, что все правильно распределено и создано.
Любые предложения о том, где мое недоразумение или неправильное использование avcodec?