ref: 05551a759c2aaa3752fa5bcecda550bfde1e896a
dir: /decoder_h264.c/
#include <h264bsd_decoder.h> #include <h264bsd_util.h> #include <thread.h> #include "frame.h" #include "stream.h" #include "decoder.h" #include "misc.h" #pragma lib "../h264bsd/src/libh264bsd.$M.a" typedef struct Aux Aux; struct Aux { storage_t c; }; static void decode(void *x) { uvlong lasttimestamp; Decoder *d; Channel *c; Frame *f; Streamframe sf; Aux *a; int res, off; u32int used, nerr, isidr, picid; u32int w, h, crop, left, top; u8int *pic; d = x; a = d->aux; lasttimestamp = 0; memset(&pic, 0, sizeof(pic)); for(res = 0; res >= 0 && (res = Sread(d->s, &sf)) == 0 && sf.sz > 0;){ off = 0; next: if((res = h264bsdDecode(&a->c, sf.buf+off, sf.sz-off, 0, &used)) < 0){ werrstr("h264bsdDecode: %r (%d)", res); break; } off += used; switch(res){ case H264BSD_PIC_RDY: if((pic = h264bsdNextOutputPicture(&a->c, &picid, &isidr, &nerr)) == nil){ werrstr("nil pic"); res = -1; }else if((f = malloc(sizeof(*f) + w*h*3)) != nil){ f->w = w; f->h = h; /* FIXME I have not a single idea what are these weird shifts based on image width */ yuv420_rgb24(w, h, pic, pic+w*h+w*8, pic+w*h*5/4+w*10, w, w/2, f->rgb, w*3); f->dt = (sf.timestamp - lasttimestamp) * d->timebase * 1000000000ULL; lasttimestamp = sf.timestamp; if(sendp(d->frames, f) < 0){ free(f); goto done; } } break; case H264BSD_HDRS_RDY: h264bsdCroppingParams(&a->c, &crop, &left, &w, &top, &h); if(!crop){ w = h264bsdPicWidth(&a->c) * 16; h = h264bsdPicHeight(&a->c) * 16; } if(w & 15) w += 16 - (w & 15); break; case H264BSD_RDY: break; case H264BSD_ERROR: res = -1; break; case H264BSD_PARAM_SET_ERROR: res = -1; werrstr("H264BSD_PARAM_SET_ERROR"); break; } if(off < sf.sz) goto next; } if(res != 0) fprint(2, "h264: %r\n"); done: h264bsdShutdown(&a->c); free(a); c = d->finished; sendp(c, res == 0 ? nil : "error"); chanclose(c); threadexits(nil); } static int h264open(Decoder *d) { Aux *a; int res; a = calloc(1, sizeof(*a)); if((res = h264bsdInit(&a->c, HANTRO_FALSE)) != 0){ werrstr("h264bsdInit: %d", res); free(a); return -1; } d->aux = a; proccreate(decode, d, 65536); return res; } static void h264close(Decoder *d) { USED(d); } Decoderops h264ops = { .open = h264open, .close = h264close, };