void VideoDecoder::DecodeThread()
{
AVPacket pkt;
int len;
uint8_t *data;
int size;
uint32_t h,w;
OrderedFramesIterator it;
bool success_push;
if(!_pkt_queue->Pop(&pkt))
return;
data = pkt.data;
size = pkt.size;
_pkt_pts = pkt.pts *_video_stream->time_base.num*1000/_video_stream->time_base.den;
int got_frame;
while (pkt.size > 0)
{
len = avcodec_decode_video2(_video_stream->codec,_av_frame,&got_frame,&pkt);
if (len < 0)
{
LOG "invalid video packet or frame. Skipping packet" EL;
break;
}
if (got_frame!=0)
{
VideoFrame video_frame;
h = _video_stream->codec->height;
w = _video_stream->codec->width;
video_frame.y = fast_alloc(uint8_t,h*w);
video_frame.u = fast_alloc(uint8_t,h*w/4);
video_frame.v = fast_alloc(uint8_t,h*w/4);
WritePlane(_av_frame->data[0],_av_frame->linesize[0],w,h,video_frame.y);
WritePlane(_av_frame->data[1],_av_frame->linesize[1],w/2,h/2,video_frame.u);
WritePlane(_av_frame->data[2],_av_frame->linesize[2],w/2,h/2,video_frame.v);
video_frame .pts = _pkt_pts;
_pkt_pts += GetFramerateDelay();
_ordered_frames.insert(make_pair(video_frame.pts, video_frame));
if (_av_frame->key_frame)
{
success_push = true;
for (it = _ordered_frames.begin();
it != _ordered_frames.end() && success_push;
++it)
success_push = _frame_queue->Push((*it).second);
if (!success_push)
{
for (;
it != _ordered_frames.end();
++it)
{
fast_free((*it).second.y);
fast_free((*it).second.u);
fast_free((*it).second.v);
}
}
_ordered_frames.clear();
}
}
pkt.size -= len;
pkt.data += len;
}
pkt.data = data;
pkt.size = size;
av_free_packet(&pkt);
}
dm9pZCBWaWRlb0RlY29kZXI6OkRlY29kZVRocmVhZCgpCnsKICAgIEFWUGFja2V0IHBrdDsKCWludCBsZW47Cgl1aW50OF90ICpkYXRhOwoJaW50IHNpemU7Cgl1aW50MzJfdCBoLHc7CiAgICBPcmRlcmVkRnJhbWVzSXRlcmF0b3IgaXQ7CiAgICBib29sIHN1Y2Nlc3NfcHVzaDsKCQoJaWYoIV9wa3RfcXVldWUtPlBvcCgmcGt0KSkKCQlyZXR1cm47CgoJZGF0YSA9IHBrdC5kYXRhOwoJc2l6ZSA9IHBrdC5zaXplOwoKCV9wa3RfcHRzID0gcGt0LnB0cyAqX3ZpZGVvX3N0cmVhbS0+dGltZV9iYXNlLm51bSoxMDAwL192aWRlb19zdHJlYW0tPnRpbWVfYmFzZS5kZW47CgoJaW50IGdvdF9mcmFtZTsKCgl3aGlsZSAocGt0LnNpemUgPiAwKQoJewoJCWxlbiA9IGF2Y29kZWNfZGVjb2RlX3ZpZGVvMihfdmlkZW9fc3RyZWFtLT5jb2RlYyxfYXZfZnJhbWUsJmdvdF9mcmFtZSwmcGt0KTsKCQkJaWYgKGxlbiA8IDApCgkJCXsKCQkJCUxPRyAgImludmFsaWQgdmlkZW8gcGFja2V0IG9yIGZyYW1lLiBTa2lwcGluZyBwYWNrZXQiIEVMOwoJCQkJYnJlYWs7CgkJCX0KCgkJCWlmIChnb3RfZnJhbWUhPTApCgkJCXsKCQkJCVZpZGVvRnJhbWUgdmlkZW9fZnJhbWU7CgoJCQkJaCA9IF92aWRlb19zdHJlYW0tPmNvZGVjLT5oZWlnaHQ7CgkJCQl3ID0gX3ZpZGVvX3N0cmVhbS0+Y29kZWMtPndpZHRoOwoKCQkJCXZpZGVvX2ZyYW1lLnkgPSBmYXN0X2FsbG9jKHVpbnQ4X3QsaCp3KTsKCQkJCXZpZGVvX2ZyYW1lLnUgPSBmYXN0X2FsbG9jKHVpbnQ4X3QsaCp3LzQpOwoJCQkJdmlkZW9fZnJhbWUudiA9IGZhc3RfYWxsb2ModWludDhfdCxoKncvNCk7CgoJCQkJV3JpdGVQbGFuZShfYXZfZnJhbWUtPmRhdGFbMF0sX2F2X2ZyYW1lLT5saW5lc2l6ZVswXSx3LGgsdmlkZW9fZnJhbWUueSk7CgkJCQlXcml0ZVBsYW5lKF9hdl9mcmFtZS0+ZGF0YVsxXSxfYXZfZnJhbWUtPmxpbmVzaXplWzFdLHcvMixoLzIsdmlkZW9fZnJhbWUudSk7CgkJCQlXcml0ZVBsYW5lKF9hdl9mcmFtZS0+ZGF0YVsyXSxfYXZfZnJhbWUtPmxpbmVzaXplWzJdLHcvMixoLzIsdmlkZW9fZnJhbWUudik7CgogICAgICAgICAgICAgICAgdmlkZW9fZnJhbWUgLnB0cyA9IF9wa3RfcHRzOwogICAgICAgICAgICAgICAgX3BrdF9wdHMgKz0gR2V0RnJhbWVyYXRlRGVsYXkoKTsKCiAgICAgICAgICAgICAgICBfb3JkZXJlZF9mcmFtZXMuaW5zZXJ0KG1ha2VfcGFpcih2aWRlb19mcmFtZS5wdHMsIHZpZGVvX2ZyYW1lKSk7CiAgICAgICAgICAgICAgICBpZiAoX2F2X2ZyYW1lLT5rZXlfZnJhbWUpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgc3VjY2Vzc19wdXNoID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICBmb3IgKGl0ID0gX29yZGVyZWRfZnJhbWVzLmJlZ2luKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICBpdCAhPSBfb3JkZXJlZF9mcmFtZXMuZW5kKCkgJiYgc3VjY2Vzc19wdXNoOwogICAgICAgICAgICAgICAgICAgICAgICAgKytpdCkKICAgICAgICAgICAgICAgICAgICAgICAgc3VjY2Vzc19wdXNoID0gX2ZyYW1lX3F1ZXVlLT5QdXNoKCgqaXQpLnNlY29uZCk7CiAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgaWYgKCFzdWNjZXNzX3B1c2gpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBmb3IgKDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpdCAhPSBfb3JkZXJlZF9mcmFtZXMuZW5kKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKytpdCkKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgZmFzdF9mcmVlKCgqaXQpLnNlY29uZC55KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhc3RfZnJlZSgoKml0KS5zZWNvbmQudSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYXN0X2ZyZWUoKCppdCkuc2Vjb25kLnYpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgIF9vcmRlcmVkX2ZyYW1lcy5jbGVhcigpOwogICAgICAgICAgICAgICAgfQoJCQl9CgoJCQlwa3Quc2l6ZSAtPSBsZW47CgkJCXBrdC5kYXRhICs9IGxlbjsKCQl9CgoJcGt0LmRhdGEgPSBkYXRhOwoJcGt0LnNpemUgPSBzaXplOwoKCWF2X2ZyZWVfcGFja2V0KCZwa3QpOwp9