Hi all,

I am decoding a H264 video stream converting each frame into a raw bitmap
data. Maybe I am missing something: the problem is that I am analyzing all
the frames and, as I have seen, every 16 frames I get an wrong frame. Is
there any kind of issue or encoding problem that causes possible problems
every 16 frame?

Here is the code I have implemented,


int VideoExtract::startDecoding(char* videoData, const int videoLen)
{
// If not initialized, initialize right now
 if (!_initialized)
{
 av_register_all();
avcodec_register_all();
 _initialized = 1;
}

// Init variables and objects
_context = avformat_alloc_context();

// Save the video in a file
FILE* f = fopen(_filename, "wb");
 if (!f) return 0;
fwrite(videoData, 1, videoLen, f);
 fclose(f);

if (avformat_open_input(&_context, _filename, NULL, NULL) < 0)
 {
// Error
 avformat_free_context(_context);

// Remove the temporal file
 remove(_filename);

return 0;
 }

if (avformat_find_stream_info(_context, NULL) < 0)
 {
// Error
 avformat_free_context(_context);

// Remove the temporal file
 remove(_filename);

return 0;
 }

// Obtain the video stream of the total set of streams
 for (unsigned int k = 0; k < _context->nb_streams; ++k)
{
 if (_context->streams[k]->codec->codec_type == AVMEDIA_TYPE_VIDEO)
_video_stream_index = k;
 _context->streams[k]->codec->time_base.den = 90000;
}

_pCodecCtx = _context->streams[_video_stream_index]->codec;
 _pCodec = avcodec_find_decoder(_pCodecCtx->codec_id);

 avcodec_open(_pCodecCtx, _pCodec);

return 1;
}

int VideoExtract::getNext(VideoFrame& videoFrame)
{
int video_stream_index;

 AVPacket packet;
av_init_packet(&packet);
 int got_picture = 0;
 int res = 0;
 // Allocate video frame
AVFrame* pFrame = avcodec_alloc_frame();

while (av_read_frame(_context, &packet) >= 0 && !got_picture)
 {
// Everything is OK, continue
 if (packet.stream_index == _video_stream_index)
{
 if (avcodec_decode_video2(_pCodecCtx, pFrame, &got_picture, &packet) < 0)
{
 // Error
}

if (got_picture)
{
 // For each image, conversion...

////////////////////////////////////////////////
 // Prepare the conversion parameters
int srcWidth = pFrame->width;
 int srcHeight = pFrame->height;
int dstWidth = srcWidth;
 int dstHeight = srcHeight;
AVPixelFormat srcFormat = _pCodecCtx->pix_fmt;
 AVPixelFormat dstFormat = AV_PIX_FMT_BGR24;
////////////////////////////////////////////////

// Calculate the bytes needed for the output image
 int dstBytes = avpicture_get_size(dstFormat, dstWidth, dstHeight);

 // Create buffer for the output image and input image
uint8_t* outbuffer = (uint8_t*) av_malloc(dstBytes);

// Create ffmpeg frame structures, these do not allocate space for image
data,
 // just the pointers and other information about the image
AVFrame* outpic = avcodec_alloc_frame();

// This will set the pointers in the frame structures to the right points in
 // the input and output buffers
avpicture_fill((AVPicture*) outpic, outbuffer, dstFormat, dstWidth,
dstHeight);

// Create the conversion context
SwsContext* fooContext = sws_getContext(srcWidth, srcHeight, srcFormat,
dstWidth, dstHeight, dstFormat, SWS_BICUBIC, NULL, NULL, NULL);

// Perform the conversion
sws_scale(fooContext, pFrame->data, pFrame->linesize, 0, srcHeight,
outpic->data, outpic->linesize);

unsigned int length = dstWidth * dstHeight * 3;

// Copy the data from the output buffer
 char* data = (char*) malloc(length);
memcpy(data, outbuffer, length);

// Create a new VideoFrame object and init it using the friend method 'init'
 videoFrame.load(_nFrame, pFrame->pkt_pts, data, length, pFrame->width,
pFrame->height, 3);

 ++_nFrame;

sws_freeContext(fooContext);
 avcodec_free_frame(&outpic);
av_free(outbuffer);

res = 1;
}
 }
}

// Free frame
avcodec_free_frame(&pFrame);

// Free packet
av_free_packet(&packet);

return res;
}

int VideoExtract::stopDecoding()
{
 // Free everything
avcodec_close(_pCodecCtx);
 avformat_close_input(&_context);
avformat_free_context(_context);

// Remove the temporal file
remove(_filename);

return 1;
}


Cheers,

--
Dídac Pérez
_______________________________________________
libav-api mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-api

Reply via email to