int h264_unpack_nal(h264_unpack_ctx_t *ctx , node_t *pkt , node_t *nal , void *_uargs) { int ret = 0; int skip = 0; uint8_t fu_nal_hdr = 0; unpack_ctx_t *_ctx = (unpack_ctx_t*)ctx; _ctx->cur_pkt_is_begin= 0; _ctx->cur_pkt_is_comp = 0; if((skip = get_hdr_size(_ctx, pkt, &fu_nal_hdr)) < 0) { /* pkt err */ ret = 1; goto __error; } if((_ctx->cur_pkt_type != HDR_TYPE(pkt)) || (_ctx->cur_times != pkt->times) || (mem_data(&_ctx->nal_mem) == NULL)) { /* reset && alloc nal */ int hdr_s, data_s; if(mem_data(&_ctx->nal_mem)) { printf("%s ===> err: skip next nal, lost cur nal;\n", __FUNCTION__); _ctx->parm._free(&_ctx->nal_mem); mem_data(&_ctx->nal_mem) = NULL; } _ctx->parm._size(&_ctx->parm, _uargs, &data_s, &hdr_s); printf("data_s: %d, hdr_s: %d\n", data_s, hdr_s); _ctx->nal_buf_size = data_s; _ctx->nal_buf_off = 0; _ctx->nal_mem = _ctx->parm._alloc(&_ctx->parm, data_s, hdr_s); } _ctx->cur_times = pkt->times; /* memcpy pkt to nal; */ if((mem_data_s(&pkt->mem)-skip) > (_ctx->nal_buf_size - _ctx->nal_buf_off)) { /* size not enough */ ret = -2; goto __error; } if(fu_nal_hdr) { *(mem_data(&_ctx->nal_mem)+_ctx->nal_buf_off++) = fu_nal_hdr; skip++; } memcpy(mem_data(&_ctx->nal_mem)+_ctx->nal_buf_off, mem_data(&pkt->mem)+skip, mem_data_s(&pkt->mem)-skip); _ctx->nal_buf_off += (mem_data_s(&pkt->mem)-skip); if(_ctx->cur_pkt_is_comp) { nal->times= _ctx->cur_times; mem_dup(&nal->mem, &_ctx->nal_mem); mem_data_s(&nal->mem) = _ctx->nal_buf_off; /* push nal to user */ mem_data(&_ctx->nal_mem) = NULL; ret = 1; } return ret; __error: printf("%s ===> err: %d;\n", __FUNCTION__, ret); if(mem_data(&_ctx->nal_mem)) { _ctx->parm._free(&_ctx->nal_mem); mem_data(&_ctx->nal_mem) = NULL; } return ret; }
long echld_read_frame(echld_reader_t* r, read_cb_t cb, void* cb_data) { DBG((4,"READ = echld_read_frame fd=%d",r->fd)); // it will use shared memory instead of inband communication do { hdr_t* h = (hdr_t*)r->rp; long nread; size_t fr_len = 0; size_t missing; DBG((5,"READ reader_len=%d",r->len)); if ( r->len < ECHLD_HDR_LEN) { /* read the header */ goto incomplete_header; } else if ( ! reader_has_frame(r) ) { /* read the (rest of) the frame */ goto incomplete_frame; } DBG((5,"READ we've got a frame! fr_len=%d ch=%d t='%c' rh=%d",fr_len, h->h.chld_id, HDR_TYPE(h), h->h.reqh_id)); cb( &(r->rp[sizeof(hdr_t)]), HDR_LEN(h), h->h.chld_id, HDR_TYPE(h), h->h.reqh_id, cb_data); r->len = 0; r->wp = r->data; r->rp = r->data; DBG((5,"READ consumed frame!")); goto again; incomplete_header: missing = ECHLD_HDR_LEN - (r->len); DBG((5,"READ incomplete_header missing=%d",missing)); nread = reader_readv(r,missing); if (nread < 0 && errno != EAGAIN) { goto kaput; /*XXX*/ } else if (nread < (long)missing) { goto again; } else { goto incomplete_frame; } incomplete_frame: fr_len = HDR_LEN(h) + ECHLD_HDR_LEN; missing = fr_len - r->len; DBG((5,"READ incomplete_frame fr_len=%d missing=%d",fr_len ,missing)); if (missing) { nread = reader_readv(r,missing); if (nread < 0 && errno != EAGAIN) { goto kaput; /*XXX*/ } else if (nread < (long)missing) { goto again; } } } while(1); DBG((1,"READ incomplete_frame Cannot happen")); return 0; again: return 1; kaput: return -1; }