annotate libavcodec/h264_seq.c @ 9:ea1ba68cf0ed

update to match api changes + add sscc produced source
author Nina Engelhardt <nengel@mailbox.tu-berlin.de>
date Wed, 05 Jun 2013 14:43:26 +0200
parents
children
rev   line source
nengel@2 1 /*
nengel@2 2 * H.26L/H.264/AVC/JVT/14496-10/... encoder/decoder
nengel@2 3 * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at>
nengel@2 4 *
nengel@2 5 * This file is part of FFmpeg.
nengel@2 6 *
nengel@2 7 * FFmpeg is free software; you can redistribute it and/or
nengel@2 8 * modify it under the terms of the GNU Lesser General Public
nengel@2 9 * License as published by the Free Software Foundation; either
nengel@2 10 * version 2.1 of the License, or (at your option) any later version.
nengel@2 11 *
nengel@2 12 * FFmpeg is distributed in the hope that it will be useful,
nengel@2 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
nengel@2 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
nengel@2 15 * Lesser General Public License for more details.
nengel@2 16 *
nengel@2 17 * You should have received a copy of the GNU Lesser General Public
nengel@2 18 * License along with FFmpeg; if not, write to the Free Software
nengel@2 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
nengel@2 20 */
nengel@2 21 #include "h264_types.h"
nengel@2 22 #include "h264_parser.h"
nengel@2 23 #include "h264_nal.h"
nengel@2 24 #include "h264_entropy.h"
nengel@2 25 #include "h264_rec.h"
nengel@2 26 #include "h264_pred_mode.h"
nengel@2 27 #include "h264_misc.h"
nengel@2 28 // #undef NDEBUG
nengel@2 29 #include <assert.h>
nengel@2 30
nengel@2 31 static int decode_slice_entropy_seq(H264Context *h, EntropyContext *ec, H264Slice *s, GetBitContext *gb, H264Mb *mbs){
nengel@2 32 int i,j;
nengel@2 33 // GetBitContext *gb = s->gb;
nengel@2 34 CABACContext *c = &ec->c;
nengel@2 35
nengel@2 36 if( !s->pps.cabac ){
nengel@2 37 av_log(AV_LOG_ERROR, "Only cabac encoded streams are supported\n");
nengel@2 38 return -1;
nengel@2 39 }
nengel@2 40
nengel@2 41 init_dequant_tables(s, ec);
nengel@2 42 ec->curr_qscale = s->qscale;
nengel@2 43 ec->last_qscale_diff = 0;
nengel@2 44 ec->chroma_qp[0] = get_chroma_qp((H264Slice *) s, 0, s->qscale);
nengel@2 45 ec->chroma_qp[1] = get_chroma_qp((H264Slice *) s, 1, s->qscale);
nengel@2 46
nengel@2 47 /* realign */
nengel@2 48 align_get_bits( gb );
nengel@2 49 /* init cabac */
nengel@2 50 ff_init_cabac_decoder( c, gb->buffer + get_bits_count(gb)/8, (get_bits_left(gb) + 7)/8);
nengel@2 51
nengel@2 52 ff_h264_init_cabac_states(ec, s, c);
nengel@2 53
nengel@2 54 for(j=0; j<ec->mb_height; j++){
nengel@2 55 init_entropy_buf(ec, s, j);
nengel@2 56 for(i=0; i<ec->mb_width; i++){
nengel@2 57 int eos,ret;
nengel@2 58 H264Mb *m = &mbs[i + j*ec->mb_width];
nengel@2 59 //memset(m, 0, sizeof(H264Mb));
nengel@2 60 m->mb_x=i;
nengel@2 61 m->mb_y=j;
nengel@2 62 ec->m = m;
nengel@2 63
nengel@2 64 ret = ff_h264_decode_mb_cabac(ec, s, c);
nengel@2 65 eos = get_cabac_terminate( c);
nengel@2 66 (void) eos;
nengel@2 67 if( ret < 0 || c->bytestream > c->bytestream_end + 2) {
nengel@2 68 av_log(AV_LOG_ERROR, "error while decoding MB %d %d, bytestream (%td)\n", m->mb_x, m->mb_y, c->bytestream_end - c->bytestream);
nengel@2 69 return -1;
nengel@2 70 }
nengel@2 71 }
nengel@2 72 }
nengel@2 73
nengel@2 74 // av_freep(&s->gb.raw);
nengel@2 75 // if (s->gb.rbsp)
nengel@2 76 // av_freep(&s->gb.rbsp);
nengel@2 77
nengel@2 78 return 0;
nengel@2 79 }
nengel@2 80
nengel@2 81
nengel@2 82
nengel@2 83 /**
nengel@2 84 * Sequential version
nengel@2 85 */
nengel@2 86 static void decode_slice_mb_seq(H264Context *h, MBRecContext *d, H264Slice *s2, H264Mb *mbs){
nengel@2 87
nengel@2 88 for (int i=0; i<2; i++){
nengel@2 89 for(int j=0; j< s2->ref_count[i]; j++){
nengel@2 90 if (s2->ref_list_cpn[i][j] ==-1)
nengel@2 91 continue;
nengel@2 92 int k;
nengel@2 93 for (k=0; k<h->max_dpb_cnt; k++){
nengel@2 94 if(h->dpb[k].reference >= 2 && h->dpb[k].cpn == s2->ref_list_cpn[i][j]){
nengel@2 95 s2->dp_ref_list[i][j] = &h->dpb[k];
nengel@2 96 break;
nengel@2 97 }
nengel@2 98 }
nengel@2 99 }
nengel@2 100 }
nengel@2 101
nengel@2 102 get_dpb_entry(h, s2);
nengel@2 103
nengel@2 104 if (!h->no_mbd){
nengel@2 105 for(int j=0; j<d->mb_height; j++){
nengel@2 106 init_mbrec_context(d, d->mrs, s2, j);
nengel@2 107 if (h->profile) printf("\n[MBREC LINE %d ", j);
nengel@2 108 for(int i=0; i<d->mb_width; i++){
nengel@2 109
nengel@2 110 if ((i & 0x7) == 0) start_timer(h, REC);
nengel@2 111 H264Mb *m = &mbs[i + j*d->mb_width];
nengel@2 112 if (h->profile==2)
nengel@2 113 pred_motion_mb_rec (d, d->mrs, s2, m);
nengel@2 114 else{
nengel@2 115 h264_decode_mb_internal(d, d->mrs, s2, m);
nengel@2 116 }
nengel@2 117 stop_timer(h, REC);
nengel@2 118 }
nengel@2 119 draw_edges(d, s2, j);
nengel@2 120
nengel@2 121 }
nengel@2 122 }
nengel@2 123
nengel@2 124 for (int i=0; i<s2->release_cnt; i++){
nengel@2 125 for(int j=0; j<h->max_dpb_cnt; j++){
nengel@2 126 if(h->dpb[j].cpn== s2->release_ref_cpn[i]){
nengel@2 127 release_dpb_entry(h, &h->dpb[j], 2);
nengel@2 128 break;
nengel@2 129 }
nengel@2 130 }
nengel@2 131 }
nengel@2 132 s2->release_cnt=0;
nengel@2 133 }
nengel@2 134
nengel@2 135 /*
nengel@2 136 * The following code is the main loop of the file converter
nengel@2 137 */
nengel@2 138 int h264_decode_seq( H264Context *h) {
nengel@2 139 ParserContext *pc;
nengel@2 140 NalContext *nc;
nengel@2 141 EntropyContext *ec;
nengel@2 142 MBRecContext *rc;
nengel@2 143 OutputContext *oc;
nengel@2 144
nengel@2 145 H264Slice slice, *s=&slice;
nengel@2 146 H264Mb *mbs;
nengel@2 147 DecodedPicture *out;
nengel@2 148 int frames=0;
nengel@2 149
nengel@2 150 #if HAVE_LIBSDL2
nengel@2 151 pthread_t sdl_thr;
nengel@2 152 if (h->display){
nengel@2 153 pthread_create(&sdl_thr, NULL, sdl_thread, h);
nengel@2 154 }
nengel@2 155 #endif
nengel@2 156
nengel@2 157 pc = get_parse_context(h->ifile);
nengel@2 158 nc = get_nal_context(h->width, h->height);
nengel@2 159
nengel@2 160 memset(s, 0, sizeof(H264Slice));
nengel@2 161 mbs = av_malloc( h->mb_height * h->mb_width * sizeof(H264Mb));
nengel@2 162
nengel@2 163 ec = get_entropy_context( h );
nengel@2 164 rc = get_mbrec_context(h);
nengel@2 165 rc->top_next = rc->top = av_malloc( h->mb_width * sizeof(TopBorder));
nengel@2 166
nengel@2 167 oc = get_output_context( h );
nengel@2 168
nengel@2 169 av_start_timer();
nengel@2 170 GetBitContext gb = {0,};
nengel@2 171 while(!pc->final_frame && frames++ < h->num_frames && !h->quit){
nengel@2 172 if (h->profile) start_timer(h, FRONT);
nengel@2 173 av_read_frame_internal(pc, &gb);
nengel@2 174 decode_nal_units(nc, s, &gb);
nengel@2 175 if (h->profile) stop_timer(h, FRONT);
nengel@2 176 // memset(s->mbs, 0, sizeof(H264Mb)*ec->mb_width*ec->mb_height);
nengel@2 177 if (h->profile) start_timer(h, ED);
nengel@2 178 decode_slice_entropy_seq(h, ec, s, &gb, mbs);
nengel@2 179 if (h->profile) stop_timer(h, ED);
nengel@2 180
nengel@2 181 if (h->profile) start_timer(h, REC);
nengel@2 182 decode_slice_mb_seq(h, rc, s, mbs);
nengel@2 183 if (h->profile) stop_timer(h, REC);
nengel@2 184
nengel@2 185 out =output_frame(h, oc, s->curr_pic, h->ofile, h->frame_width, h->frame_height);
nengel@2 186 if (out){
nengel@2 187 release_dpb_entry(h, out, 1);
nengel@2 188 }
nengel@2 189
nengel@2 190 print_report(oc->frame_number, oc->video_size, 0, h->verbose);
nengel@2 191 if (h->profile == 3){
nengel@2 192 printf("[ENTROPY %.3fms] [MBREC %.3fms]\n", h->last_time[ED] , h->last_time[REC]);
nengel@2 193 }
nengel@2 194 }
nengel@2 195 while ((out=output_frame(h, oc, NULL, h->ofile, h->frame_width, h->frame_height))) ;
nengel@2 196
nengel@2 197 print_report(oc->frame_number, oc->video_size, 1, h->verbose);
nengel@2 198 h->num_frames = oc->frame_number;
nengel@2 199 /* finished ! */
nengel@2 200 av_freep(&mbs);
nengel@2 201 av_freep(&gb.raw);
nengel@2 202 if (gb.rbsp)
nengel@2 203 av_freep(&gb.rbsp);
nengel@2 204 av_freep(&rc->top);
nengel@2 205
nengel@2 206 free_parse_context(pc);
nengel@2 207 free_nal_context (nc);
nengel@2 208 free_entropy_context(ec);
nengel@2 209 free_mbrec_context(rc);
nengel@2 210 free_output_context(oc);
nengel@2 211
nengel@2 212 #if HAVE_LIBSDL2
nengel@2 213 if (h->display){
nengel@2 214 signal_sdl_exit(h);
nengel@2 215 pthread_join(sdl_thr, NULL);
nengel@2 216 }
nengel@2 217 #endif
nengel@2 218
nengel@2 219 return 0;
nengel@2 220 }