OLD | NEW |
1 /* | 1 /* |
2 * copyright (c) 2010 Google Inc. | 2 * copyright (c) 2010 Google Inc. |
3 * | 3 * |
4 * This file is part of FFmpeg. | 4 * This file is part of FFmpeg. |
5 * | 5 * |
6 * FFmpeg is free software; you can redistribute it and/or | 6 * FFmpeg is free software; you can redistribute it and/or |
7 * modify it under the terms of the GNU Lesser General Public | 7 * modify it under the terms of the GNU Lesser General Public |
8 * License as published by the Free Software Foundation; either | 8 * License as published by the Free Software Foundation; either |
9 * version 2.1 of the License, or (at your option) any later version. | 9 * version 2.1 of the License, or (at your option) any later version. |
10 * | 10 * |
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
173 av_freep(&ctx->seq_header); | 173 av_freep(&ctx->seq_header); |
174 av_freep(&ctx->ep_header); | 174 av_freep(&ctx->ep_header); |
175 } | 175 } |
176 | 176 |
177 AVBitStreamFilter vc1_asftoannexg_bsf = { | 177 AVBitStreamFilter vc1_asftoannexg_bsf = { |
178 "vc1_asftoannexg", | 178 "vc1_asftoannexg", |
179 sizeof(ASFTOANNEXGBSFContext), | 179 sizeof(ASFTOANNEXGBSFContext), |
180 asftoannexg_filter, | 180 asftoannexg_filter, |
181 asftoannexg_close, | 181 asftoannexg_close, |
182 }; | 182 }; |
| 183 /* |
| 184 * copyright (c) 2010 Google Inc. |
| 185 * |
| 186 * This file is part of FFmpeg. |
| 187 * |
| 188 * FFmpeg is free software; you can redistribute it and/or |
| 189 * modify it under the terms of the GNU Lesser General Public |
| 190 * License as published by the Free Software Foundation; either |
| 191 * version 2.1 of the License, or (at your option) any later version. |
| 192 * |
| 193 * FFmpeg is distributed in the hope that it will be useful, |
| 194 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 195 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 196 * Lesser General Public License for more details. |
| 197 * |
| 198 * You should have received a copy of the GNU Lesser General Public |
| 199 * License along with FFmpeg; if not, write to the Free Software |
| 200 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
| 201 */ |
| 202 |
| 203 #include "avcodec.h" |
| 204 #include "bytestream.h" |
| 205 #include "vc1.h" |
| 206 |
| 207 typedef struct ASFTOANNEXGBSFContext { |
| 208 int frames; |
| 209 uint8_t *seq_header; |
| 210 int seq_header_size; |
| 211 uint8_t *ep_header; |
| 212 int ep_header_size; |
| 213 } ASFTOANNEXGBSFContext; |
| 214 |
| 215 static int parse_extradata(AVCodecContext *avctx, ASFTOANNEXGBSFContext *ctx, ui
nt8_t *extradata, int extradata_size) { |
| 216 const uint8_t *start = extradata; |
| 217 const uint8_t *end = extradata + extradata_size; |
| 218 const uint8_t *next; |
| 219 int size; |
| 220 |
| 221 if(extradata_size < 16) { |
| 222 av_log(avctx, AV_LOG_ERROR, "Extradata size too small: %i\n", extradata_
size); |
| 223 return -1; |
| 224 } |
| 225 |
| 226 start = find_next_marker(start, end); |
| 227 next = start; |
| 228 for(; next < end; start = next){ |
| 229 next = find_next_marker(start + 4, end); |
| 230 size = next - start; |
| 231 if(size <= 0) continue; |
| 232 switch(AV_RB32(start)){ |
| 233 case VC1_CODE_SEQHDR: |
| 234 ctx->seq_header = av_malloc(size); |
| 235 ctx->seq_header_size = size; |
| 236 memcpy(ctx->seq_header, start, size); |
| 237 break; |
| 238 case VC1_CODE_ENTRYPOINT: |
| 239 ctx->ep_header = av_malloc(size); |
| 240 ctx->ep_header_size = size; |
| 241 memcpy(ctx->ep_header, start, size); |
| 242 break; |
| 243 default: |
| 244 break; |
| 245 } |
| 246 } |
| 247 |
| 248 if(!ctx->seq_header || !ctx->ep_header) { |
| 249 av_log(avctx, AV_LOG_ERROR, "Incomplete extradata\n"); |
| 250 return -1; |
| 251 } |
| 252 return 0; |
| 253 } |
| 254 |
| 255 static int asftoannexg_filter(AVBitStreamFilterContext *bsfc, AVCodecContext *av
ctx, const char *args, |
| 256 uint8_t **poutbuf, int *poutbuf_size, |
| 257 const uint8_t *buf, int buf_size, int keyframe){ |
| 258 ASFTOANNEXGBSFContext* ctx = (ASFTOANNEXGBSFContext*)bsfc->priv_data; |
| 259 |
| 260 if (avctx->codec_id != CODEC_ID_VC1) { |
| 261 av_log(avctx, AV_LOG_ERROR, "Only VC1 Advanced profile is accepted!\n"); |
| 262 return -1; |
| 263 } |
| 264 |
| 265 if (!ctx->frames && parse_extradata(avctx, ctx, avctx->extradata, avctx->ext
radata_size) < 0) { |
| 266 av_log(avctx, AV_LOG_ERROR, "Cannot parse extra data!\n"); |
| 267 return -1; |
| 268 } |
| 269 |
| 270 uint8_t* bs; |
| 271 if (keyframe) { |
| 272 // If this is the keyframe, need to put sequence header and entry point
header. |
| 273 *poutbuf_size = ctx->seq_header_size + ctx->ep_header_size + 4 + buf_siz
e; |
| 274 *poutbuf = av_malloc(*poutbuf_size); |
| 275 bs = *poutbuf; |
| 276 |
| 277 memcpy(bs, ctx->seq_header, ctx->seq_header_size); |
| 278 bs += ctx->seq_header_size; |
| 279 memcpy(bs, ctx->ep_header, ctx->ep_header_size); |
| 280 bs += ctx->ep_header_size; |
| 281 } else { |
| 282 *poutbuf_size = 4 + buf_size; |
| 283 *poutbuf = av_malloc(*poutbuf_size); |
| 284 bs = *poutbuf; |
| 285 } |
| 286 |
| 287 // Put the frame start code and frame data. |
| 288 bytestream_put_be32(&bs, VC1_CODE_FRAME); |
| 289 memcpy(bs, buf, buf_size); |
| 290 ++ctx->frames; |
| 291 return 0; |
| 292 } |
| 293 |
| 294 static void asftoannexg_close(AVBitStreamFilterContext *bsfc) { |
| 295 ASFTOANNEXGBSFContext *ctx = bsfc->priv_data; |
| 296 av_freep(&ctx->seq_header); |
| 297 av_freep(&ctx->ep_header); |
| 298 } |
| 299 |
| 300 AVBitStreamFilter vc1_asftoannexg_bsf = { |
| 301 "vc1_asftoannexg", |
| 302 sizeof(ASFTOANNEXGBSFContext), |
| 303 asftoannexg_filter, |
| 304 asftoannexg_close, |
| 305 }; |
OLD | NEW |